xpath:所有节点都有例外?

xpath: All nodes with exceptions?

提问人:balin 提问时间:7/3/2023 更新时间:7/4/2023 访问量:41

问:

这是我第一次涉足,我失败得很惨。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>

我正在寻找一种表达式(同时保持树结构)

  1. 返回所有命名的节点,dependent
  2. 返回命名的节点,这些节点没有名为dependentpolarity
  3. 返回属性设置为 的节点。dependentpolaritypositive

因此,上述示例将导致:

<node1>
  <node11>
    <dependent>Retain</dependent>
    <dependent polarity="positive">Retain</dependent>
  </node11>
  <dependent>Retain</dependent>
  <dependent polarity="positive">Retain</dependent>
  <somethingelse>Retain</somethingelse>
</node1>

许多谷歌和 ChatGPL 的尝试都没有产生我想要的东西。以下是我认为应该起作用的,但不是 - 节点被保留!?polarity='negative'

//*[not(self::dependent) or (descendant-or-self::dependent[not(@polarity)]) or (descendant-or-self::dependent[@polarity='positive'])]

我在哪里犯错?

xml xpath xml 解析

评论


答:

3赞 Daniel Haley 7/3/2023 #1

你可以使用这样的东西:

//*[not(self::dependent[@polarity!='positive'])]

但是,由于您正在选择每个元素,因此它将选择根元素(),无论如何,这将包括所有内容。如果尝试修改树,可能需要使用 xquery 或 xslt。node1

产生所需输出的 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>

评论

0赞 balin 7/4/2023
谢谢 @daniel-haley 和 @michael-kay 的解释。掠夺谷歌用户试图强制使用不正确的工具的经典案例......我正在尽快在我的工具包(我已经找到了相应的包)中尝试并报告。非常感谢。Rxslt
0赞 Daniel Haley 7/4/2023
@balin - 很可能你的 R xslt 包不支持 XSLT 3.0。我用 XSLT 1.0 版本的样式表更新了我的答案。
0赞 balin 8/8/2023
中断一段时间后,我又回到了这里,并使(XSLT 1.0 版本)与 s 包结合使用。因此标记了这个答案。再次感谢。Rxslt
3赞 Michael Kay 7/3/2023 #2

XPath 旨在从输入中选择一组节点;它不能用于创建包含某些原始节点而不是其他节点的修改后的树结构。为此,您需要 XSLT 或 XQuery。

在 XSLT 3.0 中,您将使用一组如下所示的模板规则来完成任务:

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="dependent[@polarity!='positive']"/>

声明说,默认情况下,您希望将元素节点和 apply-templates 复制到它们的子节点;该规则规定,如果找到一个以非 then 命名的元素,则不希望产生与该节点相关的输出。xsl:modexsl:templatedependentpolaritypositive

评论

0赞 balin 7/4/2023
谢谢你的解释。掠夺谷歌用户试图强制使用不正确的工具的经典案例......我正在尽快在我的工具包(R,我已经找到了相应的 xsltpackage)中尝试并报告。非常感谢。
0赞 Michael Kay 7/5/2023
请注意,我给了你 XSLT 3.0 代码,Microsoft 的开箱即用 XSLT 处理器仅支持 1.0。这在 XSLT 1.0 中很容易做到,它只需要 10 行代码而不是 2 行代码。