XSLT Transformation: Search nodes, and return hierarchical parents

笑着哭i 提交于 2019-12-11 06:15:55

问题


hoping this hasn't been asked before, but I have the following 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>

I have the following XPath to search for nodes: //*[contains(translate(@name, "ABCDEFGHJIKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"), "005")]

I would like this to return:

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

So this matches the Company1005 node, and all its respective parents. I would like the above to also be returned if I were searching for "100", which in that case, would match each element in turn, but I clearly don't want duplication of nodes.

I've been struggling with this for hours now, so your help will be much appreciated!!!

Thanks.


回答1:


The solution is to copy only descendant or self nodes which match your requirement (containing the string you want).

Look this picture at the bottom of this page for the XPath axes you need.

Long version:

<?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>

Short version:

<?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>

Output of your 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>


来源:https://stackoverflow.com/questions/6282357/xslt-transformation-search-nodes-and-return-hierarchical-parents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!