xml 如何编写 xpath 以匹配除特定元素之外的所有元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4859831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:33:01  来源:igfitidea点击:

How to write a xpath to match all elements except a particular element

xmlxsltxpath

提问by Unmesh Kondolikar

I am writing an XSL transformation. I want to write a template which matches all the child elements of the document except one particular node. My xml looks like this -

我正在编写一个 XSL 转换。我想编写一个模板,该模板匹配文档的所有子元素,但一个特定节点除外。我的 xml 看起来像这样 -

<Document>
    <NodeA></NodeA>

    <NodeB></NodeB>

    <ServiceNode></ServiceNode>

    <NodeX></NodeX>
</Document>

I want to write a template that matches all nodes except ServiceNodei.e. NodeAto NodeX. How to write this Xpath to get -

我想编写一个模板来匹配除ServiceNodeie NodeAto之外的所有节点NodeX。如何编写此 Xpath 以获取 -

<xsl:template match="ALL Nodex Except ServiceNode">

回答by Dimitre Novatchev

I want to write a template that matches all nodes except ServiceNode i.e. NodeA to NodeX.

我想编写一个模板来匹配除 ServiceNode 之外的所有节点,即 NodeA 到 NodeX。

If by "node" you mean element, then use:

如果“节点”是指元素,则使用

<xsl:template match="*[not(self::ServiceNode)]">

If by "node" you mean any node (of type element, text, comment, processing-instruction): use

如果“节点”是指任何节点(元素、文本、注释、处理指令类型):使用

<xsl:template match="node()[not(self::ServiceNode)]">

If you want only children of Documentto be matched use:

如果您只想Document匹配的孩子使用:

<xsl:template match="Document/node()[not(self::ServiceNode)]">

If you want only children of the top element to be matched use:

如果您只想匹配顶部元素的子元素,请使用:

<xsl:template match="/*/node()[not(self::ServiceNode)]">

回答by Flack

You should better use this expression:

你最好使用这个表达式:

*[not(self::ServiceNode)]

As incorporated in an XSLT:

包含在 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>&#xA;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

With this XML sample:

使用此 XML 示例:

<Document>
    <NodeA>1</NodeA>
    <NodeB>2</NodeB>
    <ServiceNode>3</ServiceNode>
    <NodeX>4</NodeX>
</Document>

It will give a correct result:

它将给出正确的结果:

1
2
4

回答by Nick Jones

You could use two templates:

您可以使用两个模板:

<xsl:template match="Document/*">
   ...do something...
</xsl:template>


<xsl:template match="Document/ServiceNode" />

The later template will take priority, so the first template will match everything except ServiceNode.

后面的模板将优先,因此第一个模板将匹配除 ServiceNode 之外的所有内容。

回答by user568826

<xsl:template match="Document/*[name() != 'ServiceNode']">

(or local-name()if you have to deal with namespaces)

(或者local-name()如果您必须处理名称空间)

回答by Amit Patel

/Document/*[not(name()='ServiceNode')]