XPATH表达式以跳过带属性的行

huangapple go评论56阅读模式
英文:

XPATH expression to skip lines with attributes

问题

//*[@resource_id] 选择具有 resource_id 属性的节点,而 //*[not(@resource_id)] 选择所有不具有 resource_id 属性的节点以及没有属性的节点。要排除具有 resource_id 属性的节点,您可以使用以下 XPath 表达式:

//*[not(@resource_id)]

这将选择所有没有 resource_id 属性的节点,并排除具有该属性的节点。这应该产生您期望的输出。

如果这个解决方案仍然不起作用,可能是由于 XML 结构或其他因素导致的问题。您可以检查 XML 文件以确保它符合您的预期结构,并排除其他问题。

英文:

I've got an XML with some nested nodes, say something like:

<root>
    <inner1>
        <foo resource_id="{123}">Line1</foo>
        <bar>Line2</bar>
    </inner1>
    <inner2>
        <inner3>
            <foo>Line3</foo>
            <bar resource_id="{456}">Line4</bar>
        </inner3>
    </inner2>
</root>

The lines with attribute resource_id can appear at any level in the XML file. I need to get an xpath that gives me the exact same file contents, but without the lines/nodes containing resource_id attribute. So the ideal output would be:

<root>
    <inner1>
        <bar>Line2</bar>
    </inner1>
    <inner2>
        <inner3>
            <foo>Line3</foo>
        </inner3>
    </inner2>
</root>

I've tried several xpath commands, but without success yet :/
I don't understand why this xpath:

//*[@resource_id]

Properly selects the nodes with the aforementioned attribute, but the command:

//*[not(@resource_id)]

selects all the nodes, even the ones with resource_id attribute.

答案1

得分: 1

XPath 选择现有树中的节点,因此,例如使用 //*[not(@resource_id)],您将获得不具有 resource_id 属性的节点集或节点序列,但仍在现有树中,这意味着您选择具有 resource_id 属性的元素的任何祖先以及它们的子代/后代不会发生变化,它们仍然包含具有 resource_id 属性的元素。

这意味着仅使用XPath无法强大到足以为您提供所需的结果,其中您希望获取一个新的树,其中已过滤掉具有 resource_id 属性的元素,您可以使用XSLT或XQuery,例如:

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

<xsl:template match="*[@resource_id]"/>

在XSLT 3中,以上代码足以删除具有 resource_id 属性的任何元素。

英文:

XPath selects nodes in an existing tree so with e.g. //*[not(@resource_id)] you will get a node-set or sequence of nodes not having a resource_id attribute, but within the existing tree, meaning you select any ancestor of the elements with resource_id attribute and of course their children/descendants don't change, they continue to contain the elements with resource_id attribute.

That means that XPath alone is not powerful enough to give you the wanted result where you want a new tree with elements with resource_id attribute filtered out, you can use XSLT or XQuery for that e.g.

&lt;xsl:mode on-no-match=&quot;shallow-copy&quot;/&gt;

&lt;xsl:template match=&quot;*[@resource_id]&quot;/&gt;

in XSLT 3 will suffice to remove any elements with a resource_id attribute.

huangapple
  • 本文由 发表于 2023年6月6日 16:30:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76412784.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定