Как написать xpath для соответствия всем элементам, кроме определенного элемента
Я пишу XSL-преобразование. Я хочу написать шаблон, который соответствует всем дочерним элементам документа, кроме одного конкретного node. Мой xml выглядит так:
<Document>
<NodeA></NodeA>
<NodeB></NodeB>
<ServiceNode></ServiceNode>
<NodeX></NodeX>
</Document>
Я хочу написать шаблон, который соответствует всем узлам, кроме ServiceNode
i.e. NodeA
to NodeX
. Как написать этот Xpath, чтобы получить -
<xsl:template match="ALL Nodex Except ServiceNode">
Ответы
Ответ 1
Я хочу написать шаблон, который соответствует всем узлам, кроме ServiceNode то есть NodeA к NodeX.
Если под "node" вы подразумеваете элемент, используйте:
<xsl:template match="*[not(self::ServiceNode)]">
Если на "node" вы имеете в виду любой node (типа, текста, комментария, обработки-инструкции): используйте
<xsl:template match="node()[not(self::ServiceNode)]">
Если вы хотите, чтобы были сопоставлены только дочерние элементы Document
:
<xsl:template match="Document/node()[not(self::ServiceNode)]">
Если вы хотите, чтобы были использованы только дочерние элементы верхнего элемента:
<xsl:template match="/*/node()[not(self::ServiceNode)]">
Ответ 2
Лучше использовать это выражение:
*[not(self::ServiceNode)]
Как включен в XSLT:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:apply-templates select="*[not(self::ServiceNode)]"/>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
С этим образцом XML:
<Document>
<NodeA>1</NodeA>
<NodeB>2</NodeB>
<ServiceNode>3</ServiceNode>
<NodeX>4</NodeX>
</Document>
Он даст правильный результат:
1
2
4
Ответ 3
<xsl:template match="Document/*[name() != 'ServiceNode']">
(или local-name()
, если вам нужно иметь дело с пространствами имен)
Ответ 4
Вы можете использовать два шаблона:
<xsl:template match="Document/*">
...do something...
</xsl:template>
<xsl:template match="Document/ServiceNode" />
Более поздний шаблон будет иметь приоритет, поэтому первый шаблон будет соответствовать всем, кроме ServiceNode.
Ответ 5
/Document/*[not(name()='ServiceNode')]