0
我有許多類似XML的結構的文件,但是具有未定義的名稱空間前綴。我只需要從這些文件中提取數據,而不是驗證它們。當試圖用XElement.Load
或XDocument.Load
解析時,我得到一個undefined prefix
異常。我如何做到這一點(LINQ to XML優先)?解析帶有未定義名稱空間前綴的(psuedo-)XML
我有許多類似XML的結構的文件,但是具有未定義的名稱空間前綴。我只需要從這些文件中提取數據,而不是驗證它們。當試圖用XElement.Load
或XDocument.Load
解析時,我得到一個undefined prefix
異常。我如何做到這一點(LINQ to XML優先)?解析帶有未定義名稱空間前綴的(psuedo-)XML
如果您提前知道前綴,請將它們自己添加到虛擬根節點並將該文檔添加到該虛擬節點。然後你可以解析和查詢你的實際文檔。但是,您必須將其添加到未加以解析的XML內容之前它被加載/解析。幸運的是,這可以相對簡單地完成。
例如,
XElement ParseFragment(string fragment, IDictionary<string, XNamespace> namespaces)
{
var namespaceDefs = namespaces
.Select(kvp => String.Format("xmlns:{0}=\"{1}\"", kvp.Key, kvp.Value.NamespaceName));
var xml = String.Format(
"<root {0}>{1}</root>",
String.Join(" ", namespaceDefs),
fragment);
var root = XElement.Parse(xml);
return root.Elements().Single();
}
XElement LoadFragment(TextReader fragmentReader, IDictionary<string, XNamespace> namespaces)
{
var namespaceDefs = namespaces
.Select(kvp => String.Format("xmlns:{0}=\"{1}\"", kvp.Key, kvp.Value.NamespaceName));
var sb = new StringBuilder();
sb.AppendLine(String.Format("<root {0}>", String.Join(" ", namespaceDefs)));
sb.AppendLine(fragmentReader.ReadToEnd());
sb.AppendLine("</root>");
var root = XElement.Load(new StringReader(sb.ToString()));
return root.Elements().Single();
}
然後你就可以解析/加載和查詢元素:
var fragment = @"<a:root><b:child>foo</b:child><b:child>bar</b:child></a:root>";
var namespaces = new Dictionary<string, XNamespace>
{
{ "a", "http://a.com" },
{ "b", "http://b.com" },
};
var element = ParseFragment(fragment, namespaces);
var b = namespaces["b"];
var childValues = element
.Descendants(b + "child")
.Select(child => (string)child);
如果我不事先知道的前綴,我有重複嘗試解析,並根據錯誤消息添加一個名稱空間。我會試試這個。 –