gpt4 book ai didi

xml - 在 XPath 谓词中使用祖先轴的问题

转载 作者:数据小太阳 更新时间:2023-10-29 02:05:52 25 4
gpt4 key购买 nike

使用这个源文件:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1/>
<LeafElement1/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1/>
<LeafElement1/>
</SubElement1>
</Element2>
</Root>

我想将属性 foo="bar"添加到同时满足以下条件的元素:

  1. 有同名的兄弟元素
  2. 有任何具有属性 AttributeToCheck 的祖先

结果应该是这样的:

<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1/>
<LeafElement1/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar"/>
<LeafElement1 foo="bar"/>
</SubElement1>
</Element2>
</Root>

到目前为止,这是我的 STLesheet。它添加了匹配条件 1 的属性元素,但没有考虑条件 2。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>

<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*[count(../*[name(.) = name(current())]) > 1]">
<xsl:copy>
<xsl:attribute name="foo">bar</xsl:attribute>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

错误的输出:

<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1 foo="bar"/> (incorrect)
<LeafElement1 foo="bar"/> (incorrect)
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar"/> (correct)
<LeafElement1 foo="bar"/> (correct)
</SubElement1>
</Element2>
</Root>

由于第二个模板已经正确匹配具有同名兄弟元素的元素,因此使用祖先 XPath 轴排除没有 AttributeToCheck 祖先的元素应该很容易。我向第二个模板添加了另一个谓词。

<xsl:template match="*[ancestor::*[@AttributeToCheck]][count(../*[name(.) = name(current())]) > 1]">

当我应用此样式表时,输出文档与输入文档相同,表明第二个模板不匹配任何元素。我还尝试更改新谓词以使用节点数。

<xsl:template match="*[count(ancestor::*[@AttributeToCheck]) > 0][count(../*[name(.) = name(current())]) > 1]">

这也不起作用,输出文档与输入文档相同。这是令人惊讶的,因为当我使用这个祖先表达式来输出带有 AttributeToCheck 的节点名称时,它起作用了。我对 sylesheet 进行了以下更改:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>

<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*[count(../*[name(.) = name(current())]) > 1]">
<xsl:copy>
<xsl:attribute name="foo">bar</xsl:attribute>
<xsl:attribute name="AncestorCount">
<xsl:value-of select="count(ancestor::*[@AttributeToCheck])"/>
</xsl:attribute>
<xsl:attribute name="AncestorName">
<xsl:value-of select="name(ancestor::*[@AttributeToCheck])"/>
</xsl:attribute>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

产生这个输出:

<?xml version="1.0"?>
<Root>
<Element1 id="UniqueId1">
<SubElement1/>
<SubElement2>
<LeafElement1 foo="bar" AncestorCount="0" AncestorName=""/>
<LeafElement1 foo="bar" AncestorCount="0" AncestorName=""/>
</SubElement2>
</Element1>
<Element2 id="UniqueId2" AttributeToCheck="true">
<SubElement1>
<LeafElement1 foo="bar" AncestorCount="1" AncestorName="Element2"/>
<LeafElement1 foo="bar" AncestorCount="1" AncestorName="Element2"/>
</SubElement1>
</Element2>
</Root>

我的问题是,为什么 XPath 谓词 *[ancestor::*[@AttributeToCheck]][count(../*[name(.) = name(current())]) > 1] 没有正确匹配同时符合条件 1 和 2 的元素?我应该改用什么 XPath 表达式?

最佳答案

我只会使用一个模板(模式匹配成本很高):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>

<xsl:template match="* | @*">
<xsl:copy>
<xsl:if test="count(../*[name(current()) = name()]) > 1 and ancestor::*[@AttributeToCheck='true']">
<xsl:attribute name="foo">bar</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="* | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

关于xml - 在 XPath 谓词中使用祖先轴的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1820360/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com