【问题标题】:XSLT: Use key for Parent-Child RelationsXSLT:为父子关系使用密钥
【发布时间】:2015-11-15 09:21:50
【问题描述】:

假设每个第一个“Section”->“typeAttr”都是第二个的子项(A 是父项,B 是子项),当然它们与其他“类型”相关。如何使用 xsl 并将其转换为 html?

<root>
<Type>
    <Section typeAttr="B"/>
    <Section typeAttr="A"/>
</Type>
<Type>
    <Section typeAttr="C"/>
    <Section typeAttr="B"/>
</Type>
<Type>
    <Section typeAttr="D"/>
    <Section typeAttr="B"/>
</Type> 
<Type>
    <Section typeAttr="E"/>
    <Section typeAttr="C"/>
</Type>     
</root> 

类似这样的:

<ol>
<li>
    <a>A</a>
    <ol>
        <li>
            <a>B</a>
            <ol>
                <li><a>C</a>
                    <ol>
                        <li>
                            <a>E</a>
                        </li>
                    </ol>
                </li>
                <li>
                    <a>D</a>
                </li>
            </ol>
        </li>
    </ol>
</li>
</ol>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    我相信这会返回预期的结果:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
    
    <xsl:key name="children" match="Type" use="Section[2]/@typeAttr" />
    <xsl:key name="parent" match="Type" use="Section[1]/@typeAttr" />
    
    <xsl:template match="/root">
        <ol>
            <xsl:apply-templates select="Type[not(key('parent', Section[2]/@typeAttr))]" mode="ancestor"/>
        </ol>
    </xsl:template>
    
    <xsl:template match="Type" mode="ancestor">
        <li>
            <a>
                <xsl:value-of select="Section[2]/@typeAttr"/>
            </a>
            <ol>
                <xsl:apply-templates select="."/>
            </ol>
        </li>
    </xsl:template>
    
    <xsl:template match="Type">
        <li>
            <a>
                <xsl:value-of select="Section[1]/@typeAttr"/>
            </a>
            <xsl:variable name="children" select="key('children', Section[1]/@typeAttr)" />
            <xsl:if test="$children">
                <ol>
                    <xsl:apply-templates select="$children"/>
                </ol>
            </xsl:if>
        </li>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 但如果我有&lt;Type&gt;&lt;Section typeAttr="V"/&gt;&lt;Section typeAttr="A"/&gt;&lt;/Type&gt;,则为“A”声明两个名称。
    • @Warjeh 你还想要什么?添加的节点没有父节点,因此它会在顶层创建一个新分支。
    • 我在一个更简单的情况下做到了这一点,比如具有 'id'、'parentID' 的值。我稍后会检查。使用最难的方法,我认为我们可以添加一个条件来检查“顶级”元素。 (但我知道应该有一个更简单的方法)。现在我添加了另一个根来避免这个问题,但我会努力解决这个问题。所以,再次感谢。
    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多