找到不同的父节点完整路径

时间:2017-03-05 04:28:35

标签: xslt

Xml下面有两个名为“模式”和“成员”的父节点。模式是成员的平面子集。会员有树视图结构的地方。

输入Xml:

<Root>
    <Pattern name="A">
        <Member id="2" name="Member2" Selection="Yes"/>
        <Member id="3" name="Member3" Selection="Yes"/>
        <Member id="6" name="Member6" Selection="Yes"/>
        <Member id="20" name="Member20" Selection="Yes"/>
    </Pattern>  
    <Members>
        <Member id="1" name="Member1" Selection="Yes">
            <Member id="2" name="Member2" Selection="Yes">
                <Member id="3" name="Member3" Selection="Yes"/>
                <Member id="4" name="Member4" Selection="Yes"/>
            </Member>
            <Member id="5" name="Member5" Selection="Yes">
                <Member id="6" name="Member6" Selection="Yes"/>
                <Member id="7" name="Member7" Selection="Yes"/>
            </Member>
            <Member id="8" name="Member8" Selection="Yes">
                <Member id="9" name="Member9" Selection="Yes"/>
            </Member>
            <Member id="10" name="Member10" Selection="Yes">
                <Member id="11" name="Member11" Selection="Yes"/>
            </Member>
            <Member id="12" name="Member12" Selection="Yes">
                <Member id="13" name="Member13" Selection="Yes"/>
                <Member id="14" name="Member14" Selection="Yes">
                    <Member id="15" name="Member15" Selection="Yes"/>
                    <Member id="16" name="Member16" Selection="Yes">
                        <Member id="17" name="Member17" Selection="Yes">
                            <Member id="18" name="Member18" Selection="Yes"/>
                            <Member id="19" name="Member19" Selection="Yes"/>
                            <Member id="20" name="Member20" Selection="Yes"/>
                        </Member>
                    </Member>
                </Member>
            </Member>
        </Member>
    </Members>
</Root>

根据属性 id 会员来帮助我从模式获取所有父节点>

下面是Pattern Members fullPath的逻辑集。

<!-- Parent Member for Member2 -->
<Member name="Member1"/>

<!-- Parent Members for Member3 -->
<Member name="Member1.Member2"/>
<Member name="Member1"/>

<!-- Parent Members for Member6 -->
<Member name="Member1.Member5"/>
<Member name="Member1"/>

<!-- Parent Members for Member20 -->
<Member name="Member1.Member12.Member14.Member16.Member17"/>
<Member name="Member1.Member12.Member14.Member16"/>
<Member name="Member1.Member12.Member14"/>
<Member name="Member1.Member12"/>
<Member name="Member1"/>

上面的列表有重复。所以所需的输出如下

<!-- Unique Parent Members for All levels -->
<Member name="Member1"/>
<Member name="Member1.Member2"/>
<Member name="Member1.Member5"/>
<Member name="Member1.Member12.Member14.Member16.Member17"/>
<Member name="Member1.Member12.Member14.Member16"/>
<Member name="Member1.Member12.Member14"/>
<Member name="Member1.Member12"/>

谢谢,

2 个答案:

答案 0 :(得分:1)

假设您仅限于XSLT 1.0处理器,您可以使用:

- 简化归功于Martin Honnen在回答中建议的做法 -

XSLT 1.0

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

<xsl:key name="member-by-id" match="Member[ancestor::Members]" use="@id"/>

<xsl:template match="/Root">
    <output>
        <xsl:apply-templates select="key('member-by-id', Pattern/Member/@id)/ancestor::Member"/>
    </output>
</xsl:template>

<xsl:template match="Member">
    <Member>
        <xsl:attribute name="name">
            <xsl:for-each select="ancestor-or-self::Member">
                <xsl:value-of select="@name"/>
                <xsl:if test="position()!=last()">
                    <xsl:text>.</xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:attribute>
    </Member>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <Member name="Member1"/>
   <Member name="Member1.Member2"/>
   <Member name="Member1.Member5"/>
   <Member name="Member1.Member12"/>
   <Member name="Member1.Member12.Member14"/>
   <Member name="Member1.Member12.Member14.Member16"/>
   <Member name="Member1.Member12.Member14.Member16.Member17"/>
</output>

答案 1 :(得分:1)

这是一个XSLT 2.0解决方案:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output indent="yes"/>

<xsl:key name="ref" match="Members//Member" use="@id"/>

<xsl:template match="/">
    <xsl:apply-templates select="key('ref', //Pattern/Member/@id)/ancestor::Member"/>
</xsl:template>

<xsl:template match="Member">
    <Member name="{string-join(ancestor-or-self::Member/@name, '.')}"/>
</xsl:template>

</xsl:transform>

http://xsltransform.net/94AbWC2