簡體   English   中英

我可以從XmlSchemaSet創建數據集嗎?

[英]Can I create a DataSet from a XmlSchemaSet?

我從其他地方收到XmlSchemaSet對象,是否可以使用它來構造使用它的DataSet

一些背景

使用自定義XmlResolver讀取了此XmlSchemaSet ,並且原始模式文件具有xs:include元素, xs:include元素鏈接到要由自定義解析器解析的其他文件。 我證實, DataSet.ReadXmlSchema不正確讀取這些文件,即使我把它XmlReader定制XmlReaderSettings 我認為這是因為XmlReader僅解決DTD所需的uri,而xs:include引用則沒有。

可能的解決方案

當我深入研究DataSet.ReadXmlSchema的實現時,似乎它調用XSDSchema.LoadSchema(schemaSet,dataSet)方法來完成這項工作。 這就是我要的。 但是不幸的是, XSDSchemainternal ,除非我以XSDSchema方式對其進行破解,否則無法訪問。

那么還有其他解決方案可以解決這個問題嗎?

以下方法對我有用。 它獲取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;
        }
    }
}

這是我看來可行的“黑客”解決方案:

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();
}

但是我還是不喜歡黑客。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM