как игнорировать пространства имен в XPath


моя цель-извлечь определенные узлы из нескольких XML-файлов с несколькими пространствами имен с помощью XPath. Все работает нормально, пока я знаю URI пространства имен. Само имя пространства имен остается постоянным, но схемы (XSD) иногда создаются клиентом, т. е. неизвестны мне. Тогда у меня остается в основном три варианта:

  1. используйте только одну схему для пространства имен, надеясь, что ничего не пойдет не так (Могу ли я быть уверен?)

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

  3. как-то скажите xpath : "послушайте, меня не волнуют пространства имен, просто найдите все узлы с этим именем, я даже могу сказать вам имя пространства имен, а не URI". И вот в чем вопрос...

Это не повторение многочисленных" мое выражение xpath не работает, потому что я не знаю об осознании пространства имен " вопросы, как найдено здесь или здесь. Я знаю, как использовать осознание пространства имен. Только не как от него избавиться.

3 85

3 ответа:

можно использовать local-name() функции XPath. Вместо того, чтобы выбрать узел, как

/path/to/x:somenode

вы можете выбрать все узлы и фильтр для одного с правильным локальным именем:

/path/to/*[local-name() = 'somenode']

вы можете сделать то же самое в XPath2.0 в менее многословный синтаксис:

/path/to/*:somenode

Вы можете использовать Namespace = false на XmlTextReader

[TestMethod]
public void MyTestMethod()
{
    string _withXmlns = @"<?xml version=""1.0"" encoding=""utf-8""?>
<ParentTag xmlns=""http://anyNamespace.com"">
<Identification value=""ID123456"" />
</ParentTag>
";

    var xmlReader = new XmlTextReader(new MemoryStream(Encoding.Default.GetBytes(_withXmlns)));

    xmlReader.Namespaces = false;

    var content = XElement.Load(xmlReader);

    XElement elem = content.XPathSelectElement("/Identification");

    elem.Should().NotBeNull();
    elem.Attribute("value").Value.Should().Be("ID123456");
}

С :

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;