как игнорировать пространства имен с XPath - PullRequest
92 голосов
/ 14 декабря 2010

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

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

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

  3. как-то сказать xpath: «Послушай, мне нет дела до пространств имен, просто найди ВСЕ узлы с этим именем, я даже могу сказать тебе имя пространства имен, но не URI». И это вопрос здесь ...

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

Ответы [ 3 ]

137 голосов
/ 14 декабря 2010

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

/path/to/x:somenode

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

/path/to/*[local-name() = 'somenode']
16 голосов
/ 21 февраля 2017

Вы можете сделать то же самое в XPath2.0 в менее подробном синтаксисе:

/path/to/*:somenode
0 голосов
/ 19 марта 2018

Вы можете использовать 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;
...