XSLT转换:搜索节点,并返回分层父级

时间:2011-06-08 16:51:11

标签: xslt hierarchy transformation

希望以前没有问过,但我有以下XML:

<Company id="1000" name="Company1000">
   <Company id="1020" name="Company1020" />
   <Company id="1004" name="Company1004">
      <Company id="1005" name="Company1005" />
   </Company>
   <Company id="1022" name="Company1022" />
</Company>

我有以下XPath来搜索节点://*[contains(translate(@name, "ABCDEFGHJIKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"), "005")]

我希望这回事:

<Company id="1000" name="Company1000">
   <Company id="1004" name="Company1004">
      <Company id="1005" name="Company1005" />
   </Company>
</Company>

因此,这与Company1005节点及其各自的父节点相匹配。如果我在搜索“100”,我希望上面也会被返回,在这种情况下,它会依次匹配每个元素,但我显然不希望重复节点。

我一直在努力工作几个小时,所以非常感谢你的帮助!

感谢。

1 个答案:

答案 0 :(得分:2)

解决方案是仅复制符合您要求的后代或自身节点(包含您想要的字符串)。

page的底部查看此图片,了解您需要的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" encoding="UTF-8" indent="yes"/>

<xsl:strip-space elements="*"/>

<!-- Default: copy everything -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- just copy Company which descendant-or-self contain the matching string -->
<xsl:template match="Company">
    <xsl:if test="descendant-or-self::Company[contains(translate(@name, 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '005')]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

简短版本:

<?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" encoding="UTF-8" indent="yes"/>

<xsl:strip-space elements="*"/>

<!-- Default: copy everything -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- do not copy Company which do not have a descendant-or-self matching string -->
<xsl:template match="Company[not(descendant-or-self::Company[contains(translate(@name, 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '005')])]"/>

</xsl:stylesheet>

xml的输出:

<?xml version="1.0" encoding="UTF-8"?>
<Company id="1000" name="Company1000">
  <Company id="1004" name="Company1004">
    <Company id="1005" name="Company1005"/>
  </Company>
</Company>