xml - attribute - Cómo aplicar la función XPath ''substring-after''
xpath wildcard (4)
¿Cuál es la expresión XPath que usaría para obtener la cadena que sigue a ''HarryPotter:'' para cada libro?
es decir. Dado este XML:
<bookstore>
<book>
HarryPotter:Chamber of Secrets
</book>
<book>
HarryPotter:Prisoners in Azkabahn
</book>
</bookstore>
Me gustaría volver:
Chamber of Secrets
Prisoners in Azkabahn
He intentado algo como esto:
/bookstore/book/text()[substring-after(. , ''HarryPotter:'')]
Creo que mi sintaxis es incorrecta ...
La expresión XPath
/bookstore/book/text()[substring-after(. , ''HarryPotter:'')]
devolverá un conjunto de nodos con todos los nodos de texto que contengan el valor "HarryPotter:". Para que el título del libro sea exitoso con "HarryPotter:" debe pasar por este conjunto de nodos y buscar esa subcadena para cada nodo. Esto se puede hacer con substring-after si está usando XSLT o con Substring e IndexOf si está usando VB como lo muestra balabaster.
En tu XML no tienes espacio entre Harry Potter pero en tu XQuery tienes espacio. Simplemente haz que coincida y listo, recuperarás datos ...
Dim xml = <bookstore>
<book>HarryPotter:Chamber of Secrets</book>
<book>HarryPotter:Prisoners in Azkabahn</book>
<book>MyDummyBook:Dummy Title</book>
</bookstore>
Dim xdoc As New Xml.XmlDocument
xdoc.LoadXml(xml.ToString)
Dim Nodes = xdoc.SelectNodes("/bookstore/book/text()[substring-after(., ''HarryPotter:'')]")
Dim Iter = Nodes.GetEnumerator()
While Iter.MoveNext
With DirectCast(Iter.Current, Xml.XmlNode).Value
Console.WriteLine(.Substring(.IndexOf(":") + 1))
End With
End While
En XPath 2.0 esto puede ser producido por una sola expresión XPath:
/*/*/substring-after(., ''HarryPotter:'')
Aquí estamos utilizando la característica muy poderosa de XPath 2.0 que, al final de una ruta de pasos de ubicación, podemos poner una función y esta función se aplicará a todos los nodos en el conjunto de resultados actual.
En XPath 1.0 no existe tal característica y esto no se puede lograr en una expresión XPath.
Podríamos realizar una transformación XSLT como la siguiente:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:for-each select="/*/*[substring-after(., ''HarryPotter:'')]"> <xsl:value-of select= "substring-after(., ''HarryPotter:'')"/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
Cuando se aplica en el documento XML original:
<bookstore> <book> HarryPotter:Chamber of Secrets </book> <book> HarryPotter:Prisoners in Azkabahn </book> </bookstore>
esta transformación produce el resultado deseado:
Cámara de los Secretos
Prisioneros en Azkabahn
Xpath:
substring-after(//book, ''Advertised:'')
Soy totalmente nuevo en esta área, ¡pero para mí funciona ...!