【问题标题】:Can I create a DataSet from a XmlSchemaSet?我可以从 XmlSchemaSet 创建数据集吗?
【发布时间】:2014-06-01 01:47:51
【问题描述】:

我从其他地方收到一个XmlSchemaSet 对象,是否可以使用它来构造一个使用它的DataSet

一些背景

XmlSchemaSet 是使用自定义XmlResolver 读取的,并且原始架构文件具有链接到要由自定义解析器解析的其他文件的xs:include 元素。我确认DataSet.ReadXmlSchema 没有正确读取这些文件,即使我发送了带有自定义XmlReaderSettingsXmlReader。我认为这是因为 XmlReader 仅解析 DTD 所需的 uri,而 xs:include 引用不是。

可能的解决方案

当我深入研究DataSet.ReadXmlSchema 的实现时,它似乎调用XSDSchema.LoadSchema(schemaSet,dataSet) 方法来完成这项工作。这就是我要的。但不幸的是,XSDSchemainternal,除非我以某种方式破解它,否则无法访问。

那么还有其他解决方案可以解决这个问题吗?

【问题讨论】:

    标签: c# dataset xsd


    【解决方案1】:

    以下方法对我有用。它获取 xmlSchemaSet 的字符串表示形式,然后使用 StringReader 读取它,这是 readXmlSchema 方法可以接受的。

    public static class Utilities
    {
        public static DataSet ToDataSet(this XmlSchemaSet xmlSchemaSet)
        {
            var schemaDataSet = new DataSet();
            string xsdSchema = xmlSchemaSet.GetString();
            schemaDataSet.ReadXmlSchema(new StringReader(xsdSchema));
            return schemaDataSet;
        }
    
        private static string GetString(this XmlSchemaSet xmlSchemaSet)
        {
            var settings = new XmlWriterSettings
                           {
                               Encoding = new UTF8Encoding(false, false),
                               Indent = true,
                               OmitXmlDeclaration = false
                           };
    
            string output;
            using (var textWriter = new StringWriterWithEncoding(Encoding.UTF8))
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
                {
                    foreach (XmlSchema s in xmlSchemaSet.Schemas())
                    {
                        s.Write(xmlWriter);
                    }
                }
                output = textWriter.ToString();
            }
            return output;
        }
    }
    
    public sealed class StringWriterWithEncoding : StringWriter
    {
        private readonly Encoding _encoding;
    
        public StringWriterWithEncoding(Encoding encoding)
        {
            _encoding = encoding;
        }
    
        public override Encoding Encoding
        {
            get
            {
                return _encoding;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是我似乎可行的“黑客”解决方案:

      private static Action<XmlSchemaSet, DataSet> GetLoadSchemaMethod()
      {
          var type = (from aN in Assembly.GetExecutingAssembly().GetReferencedAssemblies()
              where aN.FullName.StartsWith("System.Data")
              let t = Assembly.Load(aN).GetType("System.Data.XSDSchema")
              where t != null
              select t).FirstOrDefault();
      
          var pschema = Expression.Parameter(typeof (XmlSchemaSet));
          var pdataset = Expression.Parameter(typeof (DataSet));
          var exp = Expression.Lambda<Action<XmlSchemaSet, DataSet>>(Expression.Call
              (Expression.New(type.GetConstructor(new Type[] {}), new Expression[] {}),
                  type.GetMethod("LoadSchema", new[]
                  {
                      typeof (XmlSchemaSet), typeof (DataSet)
                  }), new Expression[]
                  {
                      pschema, pdataset
                  }), new[] {pschema, pdataset});
      
          return exp.Compile();
      }
      

      但是我还是不想做黑客。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-23
        • 2019-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 2011-12-21
        • 2013-03-01
        相关资源
        最近更新 更多