[英]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)
方法來完成這項工作。 這就是我要的。 但是不幸的是, XSDSchema
是internal
,除非我以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.