Разбор XDocument без необходимости задавать пространство имен по умолчанию - PullRequest
12 голосов
/ 12 сентября 2011

У меня есть некоторые данные XML (аналогично примеру ниже), и я хочу прочитать значения в коде.

Почему я вынужден указать пространство имен по умолчанию для доступа к каждому элементу?Я ожидал, что пространство имен по умолчанию будет использоваться для всех элементов.

Есть ли более логичный способ достижения моей цели?

Пример XML:

<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
    <MessageHeader>
        <MessageID>00000173</MessageID>
        <Timestamp>2009-10-28T16:50:01</Timestamp>
        <MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
    </MessageHeader>
    <Receipts>
        <Receipt>
            <Status>OK</Status>
        </Receipt>
    </Receipts>
</ReceiptsBatch>

Кодчитать элементы XML, которые я ищу:

XDocument xDoc = XDocument.Load( FileInPath );

XNamespace ns = "http://www.secretsonline.gov.uk/secrets";

XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");

Ответы [ 5 ]

6 голосов
/ 29 августа 2013

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

/// <summary>
/// Makes parsing easier by removing the need to specify namespaces for every element.
/// </summary>
private static void RemoveNamespaces(XDocument document)
{
    var elements = document.Descendants();
    elements.Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    foreach (var element in elements)
    {
        element.Name = element.Name.LocalName;

        var strippedAttributes =
            from originalAttribute in element.Attributes().ToArray()
            select (object)new XAttribute(originalAttribute.Name.LocalName, originalAttribute.Value);

        //Note that this also strips the attributes' line number information
        element.ReplaceAttributes(strippedAttributes.ToArray());
    }
}
5 голосов
/ 28 ноября 2016

Вы можете использовать XmlTextReader.Namespaces свойство для отключения пространств имен при чтении файла XML.

string filePath;
XmlTextReader xReader = new XmlTextReader(filePath);
xReader.Namespaces = false;
XDocument xDoc = XDocument.Load(xReader);
2 голосов
/ 12 сентября 2011

Так работает Linq-To-Xml.Вы не можете найти какой-либо элемент, если он не находится в пространстве имен по умолчанию, и то же самое верно и для его потомков.Самый быстрый способ избавиться от пространства имен - это удалить ссылку на пространство имен из вашего исходного XML.

1 голос
/ 12 сентября 2011

Теория заключается в том, что значение документа не зависит от выбора пользователем префиксов пространства имен. Пока данные находятся в пространстве имен http://www.secretsonline.gov.uk/secrets,, не имеет значения, выберет ли автор префикс «s», «секреты», «_x.cafe.babe» или префикс «null» (то есть, делая его пространством имен по умолчанию). Ваше приложение не должно заботиться: важен только URI. Вот почему ваше приложение должно указывать URI.

1 голос
/ 12 сентября 2011

Обратите внимание, что элемент Receipts также находится в пространстве имен http://www.secretsonline.gov.uk/secrets, поэтому XNamespace также потребуется для доступа к элементу:

XElement MessageBody = xDoc.Element(ns + "Receipts");

В качестве альтернативы использованию пространств именчто вы можете использовать xpath «без учета пространства имен», используя local-name() и namespace-uri(), например,

/*[local-name()='SomeElement' and namespace-uri()='somexmlns']

Если вы пропустите предикат namespace-uri:

/*[local-name()='SomeElement']

Будет соответствовать ns1:SomeElement и ns2:SomeElement и т. д. IMO Я всегда предпочел бы XNamespace, где это возможно, и варианты использования для независимого от пространства имен xpath весьма ограничены, например, для анализа конкретных элементов в документах с неизвестными схемами (например, в служебной шине)или лучший анализ документов, где пространство имен может измениться (например, проверка будущего, где xmlns изменяется в соответствии с новой версией схемы документа)

...