Tengo problemas para seleccionar un elemento con un atributo que termina con un valor determinado.

XML se parece a

<root>
<object name="1_2"><attribute name="show" value="example"></object>
<object name="1_1"><attribute name="show" value="example"></object>
<object name="2_1"><attribute name="show" value="example"></object>
</root>

Entonces necesito extraer todos los valores de los atributos en los objetos que terminan con _1, ¿cómo puedo hacer eso?

Hice este código

 XmlNodeList childnodes = xRoot.SelectNodes("//Object[@Name='1_1']");
        foreach (XmlNode n in childnodes)
            Console.WriteLine(n.SelectSingleNode("Attribute[@Name='show']").OuterXml);

Pero no puedo encontrar cómo buscar la parte del nombre de los atributos y cómo obtener el valor exacto del parámetro de destino.

3
tehdima 18 feb. 2018 a las 18:14

2 respuestas

La mejor respuesta

En primer lugar, tenga en cuenta que XML y XPath distinguen entre mayúsculas y minúsculas, por lo que Object es diferente de object y Name es diferente de name.

XPath 2.0

Esta expresión XPath 2.0,

//object[ends-with(@name,'_1')]

Seleccionará todos los elementos object cuyo valor de atributo name termine con _1.

XPath 1.0

XPath 1.0 carece de la función ends-with() pero puede lograr el mismo resultado con un poco más de trabajo:

ends-with($s, $e) ≡ (substring($s, string-length($s) - string-length($e) +1) = $e)

Aplicado a su caso donde $s es @name y $e es '_1', lo anterior se simplifica a esta expresión:

//object[substring(@name, string-length(@name) - 1) = '_1']
6
kjhughes 8 ene. 2020 a las 23:42

Si C# admite XPath 2.0, debería poder utilizar:

XmlNodeList childnodes = xRoot.SelectNodes("//object[ends-with(@name, '_1')]");

Si no, debería funcionar una versión un poco más larga:

XmlNodeList childnodes = xRoot.SelectNodes("//object[substring(@name, string-length(@name) - 1) = '_1']");

Además, su xml no es válido ya que necesita cerrar los elementos attribute:

<root>
  <object name="1_2"><attribute name="show" value="example"/></object>
  <object name="1_1"><attribute name="show" value="example"/></object>
  <object name="2_1"><attribute name="show" value="example"/></object>
</root>
2
Jan-Peter Vos 18 feb. 2018 a las 15:37