Я пытаюсь собрать вместе выражение XPath, которое даст мне все дочерние элементы узла, которые соответствуют фильтру (например, [содержит (@class, "интересно))], но которые не имеют определенного предка например, [содержит (@class, "frame")]. Вероятно, лучше всего объяснить на примере:
<div class="frame">
<p class="interesting">alice</p>
<p class="interesting">bob</p>
<p class="interesting">carol>/p>
<div>
<div>
<h3 class="interesting">david</h3>
</div>
</div>
<div class="frame">
<p class="interesting">drevil</p>
</div>
</div>
Так что в этом примере я хочу иметь возможность сопоставить все "интересные" элементы, которые являются потомками первого элемента div с class = "frame". Но я не хочу, чтобы "интересные" элементы находились под вложенным элементом "frame".
В идеале у меня было бы одно выражение XPath, которое давало бы мне элементы с содержимым alice, bob, carol и david. Но не древил.
Это похоже на то, что наличие вложенной рамки исключает эту ветвь дерева из поиска.
Есть идеи? Все отзывы очень ценятся.
В ответ Роберту у меня есть этот код Python (хотя я сделаю это на стороне браузера):
from lxml import etree
from StringIO import StringIO
testxml = """
<div>
<div class="frame">
<p class="interesting">alice</p>
<p class="interesting">bob</p>
<p class="interesting">carol</p>
<div>
<div>
<h3 class="interesting">david</h3>
</div>
</div>
<div class="frame">
<p class="interesting">drevil</p>
</div>
</div>
</div>
"""
xsl = """
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<output>
<xsl:apply-templates select="//div[@class='frame'][1]/*"/>
</output>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*[@class='frame']"/>
<xsl:template match="*[@class='interesting']">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
"""
def test_xsl():
xslt_doc = etree.parse(StringIO(xsl))
transform = etree.XSLT(xslt_doc)
doc = etree.parse(StringIO(testxml))
result = transform(doc)
print result
if __name__=="__main__":
test_xsl()
Это дает следующий результат:
<?xml version="1.0"?>
<output>
<p class="interesting">alice</p>
<p class="interesting">bob</p>
<p class="interesting">carol</p>
<h3 class="interesting">david</h3>
<p class="interesting">drevil</p>
</output>
Как вы видите, древил скрывается.
Обратите внимание, что Томалак прав в том, что 2-е совпадение при * не имеет никакого эффекта (кроме удаления пробелов из вывода, что немного странно!).
Это просто косяк, хотя я, возможно, не смогу воспользоваться XSLT-подходом. Весь смысл запроса XPath в первую очередь заключался в получении ссылок на узлы в исходном HTML-документе. Если я выполню преобразование, узлы, содержащиеся в результирующем документе new , будут копиями, а не оригинальными, которые я ищу, и, следовательно, бесполезны!
Возможно, это самый глупый вопрос, но есть ли способ сохранить ссылки из узлов в преобразованном документе на узлы в оригинале?
Спасибо Томалак, Роберт и Михал за вашу помощь. Я думаю, мне просто нужно купить книгу на XSLT ...