Любой способ удалить мусор пространства имен из файла XML? - PullRequest
0 голосов
/ 26 октября 2010

Мне нужно выбрать некоторые узлы из XML-файла (AppNamespace.xaml из XAP-файла Silverlight, не то чтобы это имело значение), но в этом файле есть пространство имен, поэтому XPath не работает.Я мог бы потратить большую часть дневного пробного и ошибочного кошмара на рабство и дисциплину XmlNamespaceManager и получить безнадежно хрупкий код, который не может допустить ни малейшего изменения во входном файле (не очень хорошая идея в рабочем коде),или я мог бы использовать нелепый синтаксис local-name () [1].

Но было бы удобнее использовать XPath в качестве понятного человеку языка запросов, который можно использовать для возврата указанных узлов или значений атрибутов из произвольных файлов XML.

Так есть ли способ убрать помехи из файла?Или я застрял?Является ли лабиринтная слабость Linq-to-XML действительно меньшим злом?

[1]

//*[local-name() = 'Deployment']/*[local-name() = 'Deployment.Parts']/*[local-name() = 'AssemblyPart']/@*[local-name()='Name']

Обновление

Через пять лет я поддерживаю термин "лабиринтная слабость" со всеми волокнами моего существа, за исключениеммало волокон, которые хотят использовать что-то гораздо более прочное.

Ответы [ 2 ]

5 голосов
/ 26 октября 2010

Ed, вот пример использования пространств имен с классом System.Xml.XPath Extensions.Я изменил его так, чтобы он соответствовал вводу, который вы просматриваете:

string markup = @"
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ...>
  <Deployment.Parts>
    <AssemblyPart x:Name="xamlName" Source="assembly" />
  </Deployment.Parts>
</Deployment>
";

XmlReader reader = XmlReader.Create(new StringReader(markup));
XElement root = XElement.Load(reader);

XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
nsm.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
nsm.AddNamespace("dep", "http://schemas.microsoft.com/client/2007/deployment");

IEnumerable<XElement> elements =
   root.XPathSelectElements("//dep:Deployment/dep:Deployment.Parts/dep:AssemblyPart/@x:Name", nsm);
foreach (XElement el in elements)
    Console.WriteLine(el);

Не очень сложно.Очевидно, вы уже знаете о XmlNamespaceManager, но я думаю, что у вас сложилось худшее впечатление, чем оно того заслуживает.

Когда вы говорите «безнадежно хрупкий код, который не может допустить ни малейшего изменения во входном файле», выобвинять пространства имен вообще или XmlNamespaceManager?Я не понимаю, как один из них делает его хрупким ... тем более, что код обработки XML без пространств имен не допустит некоторые изменения во входном документе, но допустит другие.

Имейте немного уважения к другим умным людям в отрасли, потратьте немного времени, чтобы понять преимущества дизайна, прежде чем отклонить его, и вы обычно обнаружите, что есть веские причины для того, что было сделано.

Нечто пространства имен XML не могут быть улучшены.Однако никому не удалось выработать лучший стандарт и принять его сообществом.

2 голосов
/ 26 октября 2010

В XPath 2.0 вы можете использовать подстановочные знаки пространства имен (если вы знаете, что делаете):

//*:Deployment/*:Deployment.Parts/*:AssemblyPart/@Name

Кстати. Если атрибут не имеет префикса, он вообще не находится в пространстве имен. Так как это чаще всего так, я думаю, вам не нужно local-name() для атрибута.

...