使用XSLT从XML节点列表创建HTML

And*_* N. 2 xslt

我是XSLT的菜鸟.我有一个XML,其中t节点后跟其他节点,然后另一个t节点可能再次出现,然后再次出现节点,依此类推

<t />
<n1 />
<n2 />
..

<t/>
<n3 />
<n4 />
...
Run Code Online (Sandbox Code Playgroud)

我需要将此XML转换为HTML,其中t个节点将所有节点包含在下一个t节点之后

<div class='t'>
   <div class='n1'/>
   <div class='n2'/>
    ...
</div>

<div class='t'>
   <div class='n3'/>
   <div class='n4'/>
    ...
</div>
Run Code Online (Sandbox Code Playgroud)

我很难实现这一点.任何想法\提示?

谢谢!

小智 6

这是对邻居的分组.有很多解决方案:

惠特这个良好的输入:

<root>
    <t />
    <n1 />
    <n2 />
    <t/>
    <n3 />
    <n4 />
</root>
Run Code Online (Sandbox Code Playgroud)

XSLT 1.0:遍历跟随轴

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]" mode="group"/>
            <xsl:apply-templates select="t"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="t">
        <div class="t">
            <xsl:apply-templates select="following-sibling::node()[1]"
                                 mode="group"/>
        </div>
    </xsl:template>
    <xsl:template match="t" mode="group"/>
    <xsl:template match="node()" mode="group">
        <xsl:apply-templates select="."/>
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="group"/>
    </xsl:template>
    <xsl:template match="*[starts-with(name(),'n')]">
        <div class="{name()}"/>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

XSLT 1.0:密钥

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:key name="kNodeByMark"
             match="node()[../t][not(self::t)]"
             use="generate-id((..|preceding-sibling::t[1])[last()])"/>
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="key('kNodeByMark',generate-id())"/>
            <xsl:for-each select="t">
                <div class="t">
                    <xsl:apply-templates
                         select="key('kNodeByMark',generate-id())"/>
                </div>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[starts-with(name(),'n')]">
        <div class="{name()}"/>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

XSLT 2.0:for-each-group指令

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="node()[../t[1] >> .]"/>
            <xsl:for-each-group select="node()" group-starting-with="t">
                <div class="t">
                    <xsl:apply-templates 
                         select="current-group()[position()>1]"/>
                </div>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[starts-with(name(),'n')]">
        <div class="{name()}"/>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

输出:

<root>
    <div class="t">
        <div class="n1" />
        <div class="n2" />
    </div>
    <div class="t">
        <div class="n3" />
        <div class="n4" />
    </div>
</root>
Run Code Online (Sandbox Code Playgroud)

编辑:遍历跟随轴重构,看起来像其他解决方案.剥离身份规则.