it-swarm.dev

como ignorar namespaces com XPath

Meu objetivo é extrair determinados nós de vários arquivos xml com vários namespaces usando XPath. Tudo funciona bem, desde que eu conheça os URIs de namespace. O nome do namespace em si permanece constante, mas os Schemas (XSD) às vezes são gerados pelo cliente, ou seja, desconhecidos para mim. Então me resta basicamente três opções:

  1. use apenas um esquema para o namespace, esperando que nada dê errado (posso ter certeza?)

  2. obtenha os nós filhos do documento e procure o primeiro nó com um URI de namespace, esperando que ele esteja lá e apenas use o URI, esperando que seja o correto. pode dar errado por várias razões

  3. de alguma forma dizer xpath: "olha, eu não me importo com os namespaces, basta encontrar todos os nós com este nome, eu posso mesmo dizer-lhe o nome do espaço de nomes, mas não o URI". E esta é a questão aqui ...

Isso não é uma reiteração de várias perguntas "minha expressão xpath não funciona porque não estou ciente da percepção do namespace" como encontradas aqui ou aqui . Eu sei como usar a conscientização do espaço para nome. Só não como se livrar disso.

92
kostja

Você pode usar a função XPath local-name(). Em vez de selecionar um nó como

/path/to/x:somenode

você pode selecionar todos os nós e filtrar para aquele com o nome local correto:

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

Você pode fazer o mesmo em XPath2. em uma sintaxe menos detalhada:

/path/to/*:somenode
16
Andrés Cuadros Suárez

Você poderia usar Namespace = false em um 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");
}

com:

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;
0
Pierre Vonderscher