SelectSingleNode retornar null - mesmo com o espaço de nomes
-
14-11-2019 - |
Pergunta
Eu sei que esta pergunta tem sido feita de uma forma semelhante antes, mas eu não consigo fazê-lo funcionar.
Eu tenho algumas xml:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<Research xmlns="http://www.rixml.org/2005/3/RIXML" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" createDateTime="2011-03-29T15:41:48Z" language="eng" researchID="MusiJvs3008">
<Product productID="MusiJvs3008">
<StatusInfo currentStatusIndicator="Yes" statusDateTime="2011-03-29T15:41:48Z" statusType="Published" />
<Source>
<Organization type="SellSideFirm" primaryIndicator="Yes">
<OrganizationID idType="Reuters">9999</OrganizationID>
E eu estou tentando ler valores usando xpath:
XPathDocument xmldoc = new XPathDocument(xmlFile);
XPathNavigator nav = xmldoc.CreateNavigator();
XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
nsMgr.AddNamespace(string.Empty, "http://www.rixml.org/2005/3/RIXML");
XPathNavigator result = nav.SelectSingleNode("/Research", nsMgr); // <-- Returns null!
Mas até mesmo um simples escolha do nó raiz retorna null!Eu tenho certeza que tem algo errado com o meu espaço de nomes.Alguém por favor pode ajudar?
Idealmente, eu quero que as linhas simples que vai me deixar seleccionar valores de arquivo xml, i.é.
String a = xmlDoc.SelectSingleNode(@"/Research/Product/Content/Title").Value;
BTW, eu não tenho nenhuma (direto) controle sobre o ficheiro XML de conteúdo.
Solução
Eu não acredito que você pode usar um vazio de espaço de nomes de alias e tê-lo usado automaticamente pelo a expressão XPath.Assim que você utilize uma alias, ele deve funcionar embora.Este teste é bom, por exemplo:
using System;
using System.Xml;
using System.Xml.XPath;
class Test
{
static void Main()
{
string xmlFile = "test.xml";
XPathDocument xmldoc = new XPathDocument(xmlFile);
XPathNavigator nav = xmldoc.CreateNavigator();
XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
nsMgr.AddNamespace("x", "http://www.rixml.org/2005/3/RIXML");
XPathNavigator result = nav.SelectSingleNode("/x:Research", nsMgr);
Console.WriteLine(result);
}
}
Você tem para usar XPath e XPathDocument
, pelo caminho?Eu tendem a achar que o LINQ to XML é uma muito mais agradável API, particularmente quando se trata de espaços de nomes.Se você estiver usando .NET 3.5 e você não tem exigência específica para o uso do XPath, eu sugiro que você check-out.
Outras dicas
Fazer as seguintes alterações
nsMgr.AddNamespace("x", "http://www.rixml.org/2005/3/RIXML");
XPathNavigator result = nav.SelectSingleNode("/x:Research", nsMgr);
eu poderia postar e responder a minha própria pergunta, para o nativo equivalente a este código.Em vez disso, eu só vou adicioná-lo como uma resposta para a final.
Quando utilizar o nativo IXMLDOMDocument
(versão 6) objeto:
//Give the default namespace as alias of "x"
document.setProperty("SelectionNamespaces","xmlns:x='http://www.rixml.org/2005/3/RIXML'");
//Query for the nodes we want
document.selectSingleNode("/x:Research");
Pergunta Bônus: Por que, oh por que, não é objeto de Documento Xml de consulta do modelo a padrão espaço de nomes quando não há espaço de nomes é especificado... suspiro