Usando XPath em SelectSingleNode: Recuperando elemento individual de XML se ele está presente

votos
13

Meu XML se parece com:

<?xml version=\1.0\?>
<itemSet>
       <Item>one</Item>
       <Item>two</Item>
       <Item>three</Item>
       .....maybe more Items here.
</itemSet>

Alguns do indivíduo item pode ou não estar presente. Digamos que eu queira recuperar o elemento <Item>dois</Item> se ele está presente. Eu tentei as seguintes XPaths (em C #).

  • XMLNode node = myXMLdoc.SelectSingleNode(/itemSet[Item='two'])--- Se item dois está presente, então ele me retorna somente o primeiro elemento de uma . Talvez esta consulta apenas aponta para o primeiro elemento no conjunto de itens, se ele tem um item de valor de dois em algum lugar como uma criança. Esta interpretação é a correta?

Então, eu tentei:

  • XMLNode node = myXMLdoc.SelectSingleNode(/itemSet[Item='two']/Item[1])--- Eu li essa consulta como, voltar-me o primeiro <Item>elemento dentro itemset que tem valor = 'dois'. Estou correcto?

Este ainda retorna apenas o primeiro elemento de uma . O que estou fazendo de errado? Em ambos os casos, utilizando os irmãos posso atravessar os nós filhos e ficar a dois , mas isso não é o que eu estou olhando. Além disso, se dois está ausente, em seguida, SelectSingleNode retorna nulo. Assim, o próprio fato de que eu estou recebendo um nó bem sucedido retorno não indica a presença de elemento de dois, então se eu queria um teste booleano a presença chk de dois , qualquer um dos XPaths acima seria suficiente, mas eu realmente a necessidade do elemento completo <Item>two</Item>como meu nó retorno.

[A minha primeira pergunta aqui, e minha primeira vez trabalhando com programação web, então eu só aprendeu as XPaths acima e outras coisas xml relacionado na mosca a partir de agora as questões passadas em SO. Então seja gentil e deixe-me saber se eu sou um idiota ou desrespeitar as regras comunitárias. Obrigado.]

Publicado 19/05/2009 em 17:12
fonte usuário
Em outras línguas...                            


1 respostas

votos
23

Eu acho que você quer:

myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']")

Em outras palavras, você quer o item que tem texto de dois, e não o itemSetque o contenham.

Você também pode usar um único ponto para indicar o nó de contexto, no seu caso:

myXMLdoc.SelectSingleNode("/itemSet/Item[.='two']")

EDIT: A diferença entre .e text()é que .significa "este nó" de forma eficaz, e text()significa "todos os filhos do nó texto deste nó". Em ambos os casos, a comparação vai ser contra a "cadeia de valor" do LHS. Para um nó de elemento, o valor da cadeia é "a concatenação das cordas valores de todos os descendentes do nó de texto do nó de elemento na ordem do documento" e para uma coleção de nós de texto, a comparação vai verificar se qualquer nó de texto é igual a o que você está testando.

Portanto, não importa quando o conteúdo do elemento só tem um único nó de texto, mas suponho que tivemos:

<root>
  <item name="first">x<foo/>y</item>
  <item name="second">xy<foo/>ab</item>
</root>

Em seguida, uma expressão XPath de " root/item[.='xy']" irá coincidir com o primeiro item, mas " root/item[text()='xy']" irá coincidir com o segundo.

Respondeu 19/05/2009 em 17:17
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more