example - python etree lxml
Cómo hacer coincidir un nodo de texto y luego seguir los nodos principales con XPath (2)
Estoy tratando de analizar algo de HTML con XPath. Siguiendo el ejemplo de XML simplificado a continuación, deseo hacer coincidir la cadena ''Texto 1'', luego tomar el contenido del nodo de content
relevante.
<doc>
<block>
<title>Text 1</title>
<content>Stuff I want</content>
</block>
<block>
<title>Text 2</title>
<content>Stuff I don''t want</content>
</block>
</doc>
Mi código Python arroja un tambaleante:
>>> from lxml import etree
>>>
>>> tree = etree.XML("<doc><block><title>Text 1</title><content>Stuff
I want</content></block><block><title>Text 2</title><content>Stuff I d
on''t want</content></block></doc>")
>>>
>>> # get all titles
... tree.xpath(''//title/text()'')
[''Text 1'', ''Text 2'']
>>>
>>> # match ''Text 1''
... tree.xpath(''//title/text()="Text 1"'')
True
>>>
>>> # Follow parent from selected nodes
... tree.xpath(''//title/text()/../..//text()'')
[''Text 1'', ''Stuff I want'', ''Text 2'', "Stuff I don''t want"]
>>>
>>> # Follow parent from selected node
... tree.xpath(''//title/text()="Text 1"/../..//text()'')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 1330, in lxml.etree._Element.xpath (src/
lxml/lxml.etree.c:14542)
File "xpath.pxi", line 287, in lxml.etree.XPathElementEvaluator.__ca
ll__ (src/lxml/lxml.etree.c:90093)
File "xpath.pxi", line 209, in lxml.etree._XPathEvaluatorBase._handl
e_result (src/lxml/lxml.etree.c:89446)
File "xpath.pxi", line 194, in lxml.etree._XPathEvaluatorBase._raise
_eval_error (src/lxml/lxml.etree.c:89281)
lxml.etree.XPathEvalError: Invalid type
¿Es esto posible en XPath? ¿Debo expresar lo que quiero hacer de otra manera?
¿Quieres eso?
//title[text()=''Text 1'']/../content/text()
Uso :
string(/*/*/title[. = ''Text 1'']/following-sibling::content)
Esto representa al menos dos mejoras en comparación con la solución actualmente aceptada de Johannes Weiß:
La muy costosa abreviatura "//" (que generalmente hace que se escanee todo el documento XML) se evita como debería ser siempre que la estructura del documento XML se conozca de antemano.
No se devuelve al padre (se evita el paso de ubicación "/ ..")