2013-08-19 7 views
0

У меня есть несколько файлов с XML-структурой, но с неопределенными префиксов пространств имен. Мне нужно только извлечь данные из этих файлов, а не проверять их. При попытке разобрать с XElement.Load или XDocument.Load, я получаю undefined prefix исключение. Как я могу это сделать (предпочтительно с LINQ to XML)?Синтаксический (psuedo-) XML с неопределенным пространством имен префиксов

ответ

1

Если вы знаете префиксы раньше время, добавьте их себе фиктивный корневой узел и добавить документ в этот фиктивный узел. Затем вы можете проанализировать и запросить свой фактический документ. Тем не менее, вы должны добавить это в unparsed 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); 
+0

А если я не знаю, префиксы раньше времени, я бы для повторного разбора 'try' и добавления пространства имен на основе сообщения об ошибке. Я попробую это. –