我从其他地方接收到一个XmlSchemaSet对象,是否可以使用它来构造一个使用它的DataSet?
一些背景
此XmlSchemaSet是用自定义XmlResolver读取的,原始模式文件具有链接到其他文件的xs:include元素,这些元素将由自定义解析器解析。我确认DataSet.ReadXmlSchema没有正确读取这些文件,即使我给它发送了一个带有自定义XmlReaderSettings的XmlReader。我认为这是因为XmlReader只解析DTD所需的uris,而不解析xs:include引用。
可能的解决方案
当我深入研究DataSet.ReadXmlSchema的实现时,似乎调用了XSDSchema.LoadSchema(schemaSet,dataSet)方法来完成这项工作。这就是我想要的。但不幸的是,XSDSchema是internal,除非我以某种方式破解它,否则无法访问它。
那么,还有其他解决办法可以解决这个问题吗?
发布于 2014-06-02 15:27:41
下面的方法对我有效。它获取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;
}
}
}发布于 2014-04-17 01:18:56
这里是我的“黑客”解决方案,似乎是可行的:
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();
}不过,我还是不喜欢做黑客活动。
https://stackoverflow.com/questions/23122130
复制相似问题