英文:
xpath: All nodes with exceptions?
问题
这是我的第一次尝试使用xpath
,但我失败了。
考虑这样的情况:
<node1>
<node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<dependent polarity="negative">Discard</dependent>
</node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<dependent polarity="negative">Discard</dependent>
<somethingelse>Retain</somethingelse>
</node1>
我正在寻找一个表达式,该表达式将(保持树结构的同时):
- 返回所有不命名为
dependent
的节点, - 返回没有名为
polarity
的属性的名为dependent
的节点, - 返回名为
dependent
且具有属性polarity
设置为positive
的节点。
上面的示例将如下结果:
<node1>
<node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
</node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<somethingelse>Retain</somethingelse>
</node1>
许多尝试使用Google和ChatGPT都没有产生我想要的结果。以下是我认为应该有效但实际上不起作用的内容 - polarity='negative'
节点被保留了!?
//*[not(self::dependent) or (descendant-or-self::dependent[not(@polarity)]) or (descendant-or-self::dependent[@polarity='positive'])]
我在哪里出错了?
英文:
This is my first foray into xpath
and I'm failing miserably.
Consider something like this:
<node1>
<node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<dependent polarity="negative">Discard</dependent>
</node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<dependent polarity="negative">Discard</dependent>
<somethingelse>Retain</somethingelse>
</node1>
I'm looking for an expression that will (while maintaining tree structure)
- return all nodes not named
dependent
, - return nodes named
dependent
that do not have an attribute namedpolarity
- return nodes named
dependent
with attributepolarity
set topositive
.
Above example would thus result in:
<node1>
<node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
</node11>
<dependent>Retain</dependent>
<dependent polarity="positive">Retain</dependent>
<somethingelse>Retain</somethingelse>
</node1>
Many attempts at googleing and ChatGPLing have not produced what I want. Below is what I believe should work, but doesn't - polarity='negative'
nodes are retained!?
//*[not(self::dependent) or (descendant-or-self::dependent[not(@polarity)]) or (descendant-or-self::dependent[@polarity='positive'])]
Where do I err?
答案1
得分: 3
您可以使用类似以下的内容:
//*[not(self::dependent[@polarity!='positive'])]
但由于您选择了每个元素,它将选择根元素(node1
),这将包括所有内容。如果您尝试修改树结构,您可能需要使用 xquery 或 xslt。
以下是生成所需输出的 XSLT 示例:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="dependent[@polarity!='positive']"/>
</xsl:stylesheet>
XSLT 1.0 版本(将 xsl:mode 替换为标识模板):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dependent[@polarity!='positive']"/>
</xsl:stylesheet>
英文:
You could use something like this:
//*[not(self::dependent[@polarity!='positive'])]
But since you're selecting each element, it's going to select the root element (node1
) and that's going to include everything anyway. If you're trying to modify the tree, you'll probably want to use xquery or xslt.
Example of XSLT that results in the desired output:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="dependent[@polarity!='positive']"/>
</xsl:stylesheet>
XSLT 1.0 version (replaced xsl:mode with identity template)...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dependent[@polarity!='positive']"/>
</xsl:stylesheet>
答案2
得分: 3
XPath 旨在从输入中选择一组节点;它无法用于创建一个包含一些原始节点但不包含其他节点的修改后的树结构。为此,您需要使用 XSLT 或 XQuery。
在 XSLT 3.0 中,您可以通过一组模板规则来实现您的任务,类似于以下内容:
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="dependent[@polarity!='positive']"/>
xsl:mode
声明表示默认情况下您希望复制元素节点并对其子节点应用模板;xsl:template
规则表示,如果您找到一个名为 dependent
的元素,其 polarity
值不是 positive
,则您不希望产生与该节点相关的任何输出。
英文:
XPath is designed to select a set of nodes from your input; it can't be used to create a modified tree structure containing some of the original nodes and not others. For that you need XSLT or XQuery.
In XSLT 3.0 you would achieve your task with a set of template rules something like this:
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="dependent[@polarity!='positive']"/>
The xsl:mode
declaration says that by default you want to copy element nodes and apply-templates to their children; the xsl:template
rule says that if you find an element named dependent
with a polarity
value other than positive
then you want to produce no output in respect of that node.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论