我有以下平面xml结构。
<customUI >
<elements>
<tab id="1" parent="0"/>
<tab id="-1" parent="0"/>
<group id="-2" parent="-1"/>
<group id="2" parent="1"/>
<group id="11" parent="1"/>
<menu id="-27" parent="-26"/>
<menu id="-24" parent="-4"/>
<menu id="-18" parent="-4"/>
<menu id="-11" parent="-9"/>
<menu id="-10" parent="-9"/>
<menu id="-3" parent="-2"/>
<menu id="3" parent="2"/>
<menu id="10" parent="65"/>
<menu id="12" parent="11"/>
<menu id="16" parent="11"/>
<menu id="18" parent="11"/>
<menu id="25" parent="11" />
<menu id="29" parent="11"/>
<menu id="46" parent="11"/>
<menu id="74" parent="-3"/>
<menu id="85" parent="11"/>
<menu id="89" parent="2"/>
<menu id="95" parent="2"/>
<menu id="104" parent="2"/>
<button id="-28" parent="-2"/>
<button id="-25" parent="-24"/>
<button id="-12" parent="-11"/>
<button id="32" parent="29"/>
<button id="26" parent="25"/>
<button id="41" parent="18"/>
<button id="66" parent="46"/>
<button id="82" parent="74"/>
<button id="86" parent="46"/>
<button id="87" parent="89"/>
<button id="90" parent="89"/>
<button id="99" parent="89"/>
<button id="58" parent="16"/>
<button id="42" parent="18"/>
<button id="47" parent="46"/>
<button id="48" parent="46"/>
<button id="33" parent="29"/>
<!-- The list continues -->
</elements>
</customUI>
我想要做的是使用'id'值和'parent'值之间的关系来构建层次结构。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tab">
<xsl:variable name="controllerId" select="@id" as="xs:string"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:copy-of select="//*[@parent = $controllerId]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="group" name="group">
<xsl:variable name="controllerId" select="@id" as="xs:string"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:copy-of select="//*[@parent = $controllerId]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="menu" name="menu">
<xsl:variable name="controllerId" select="@id" as="xs:string"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:copy-of select="//*[@parent = $controllerId]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是我到目前为止所尝试过的,但它不起作用。
任何帮助将不胜感激。
答案 0 :(得分:1)
这有点粗糙,但应该有效:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity template -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="elements">
<xsl:copy>
<xsl:for-each select="*">
<xsl:if test="not(../*[@id=current()/@parent])">
<xsl:apply-templates select="."/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="elements/*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="../*[@parent = current()/@id]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
elements
模板会复制它,但对于其中的每个元素,如果没有其他兄弟的父母就是这个,那么它只应用模板;即如果您的数据代表完整的层次结构,它可能只是根。
第二个模板适用于元素模板中的任何内容,并按原样复制,然后还包括递归的父元素是当前元素的任何其他元素。
使用可能更快的键的替代方法,但如果有多个elements
元素则会出现问题:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="elemsById" match="elements/*" use="@id"/>
<xsl:key name="elemsByParent" match="elements/*" use="@parent"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="elements">
<xsl:copy>
<xsl:apply-templates select="*[not(key('elemsById',@parent))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="elements/*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="key('elemsByParent',@id)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>