如果有人给我提示如何创建xslt,我会很高兴。可能是muenchian灌浆可以吗?是否可以为无限路径创建代码或者我必须限制路径元素的数量?非常感谢: - )
<DETAILS>
<DETAIL>
<PATH>A\B\C\D</PATH>
<VALUE>Value1<VALUE>
<DETAIL>
<DETAIL>
<PATH>A\B\C\E</PATH>
<VALUE>Value2<VALUE>
<DETAIL>
<DETAIL>
<PATH>A\B\C\F</PATH>
<VALUE>Value3<VALUE>
<DETAIL>
<DETAIL>
<PATH>A\C\F</PATH>
<VALUE>Value4<VALUE>
<DETAIL>
<DETAIL>
<PATH>A\C\G</PATH>
<VALUE>Value5<VALUE>
<DETAIL>
<DETAILS>
==&GT;转换为
<A>
<B>
<C>
<D>Value1</D>
<E>Value2</E>
<F>Value3</F>
</C>
</B>
<C>
<F>Value4</F>
<G>Value5</G>
</C>
</A>
答案 0 :(得分:0)
正如我在评论中所说,这并不简单,尤其是。如果仅限于XSLT 1.0。我的建议是分几步完成。第一步是将输入转换为以下内容:
<elems>
<elem level="1" parent="">A</elem>
<elem level="2" parent="A">B</elem>
<elem level="3" parent="B">C</elem>
<elem level="4" parent="C" value="Value1">D</elem>
<elem level="1" parent="">A</elem>
<elem level="2" parent="A">B</elem>
<elem level="3" parent="B">C</elem>
<elem level="4" parent="C" value="Value2">E</elem>
<elem level="1" parent="">A</elem>
<elem level="2" parent="A">B</elem>
<elem level="3" parent="B">C</elem>
<elem level="4" parent="C" value="Value3">F</elem>
<elem level="1" parent="">A</elem>
<elem level="2" parent="A">C</elem>
<elem level="3" parent="C" value="Value4">F</elem>
<elem level="1" parent="">A</elem>
<elem level="2" parent="A">C</elem>
<elem level="3" parent="C" value="Value5">G</elem>
</elems>
在第二步中,为第一级的每个不同elem
创建一个元素。
最后,您递归地将模板应用于每个元素的不同子元素 - 即比当前级别深一级且其父级名称与当前元素名称匹配的元素。
以下样式表使用EXSLT扩展函数来标记路径并仅选择不同的节点。如果您的XSLT处理器不支持这些功能,则必须使用命名递归模板进行标记化,并使用Muenchian分组来选择不同的节点。
XSLT 1.0(+ EXSLT)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:set="http://exslt.org/sets"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl set str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="children" match="elem" use="concat(@parent, '|', @level)" />
<xsl:variable name="elems">
<xsl:for-each select="/DETAILS/DETAIL">
<xsl:variable name="value" select="VALUE" />
<xsl:for-each select="str:tokenize(PATH, '\')">
<elem level="{position()}" parent="{preceding-sibling::token[1]}">
<xsl:if test="position()=last()">
<xsl:attribute name="value">
<xsl:value-of select="$value"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="."/>
</elem>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="elems-set" select="exsl:node-set($elems)" />
<xsl:template match="/">
<output>
<xsl:apply-templates select="set:distinct($elems-set/elem[@level=1])"/>
</output>
</xsl:template>
<xsl:template match="elem">
<xsl:element name="{.}">
<xsl:value-of select="@value"/>
<xsl:apply-templates select="set:distinct(key('children', concat(., '|', @level + 1)))"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,这一切都基于可能没有同名兄弟元素的假设。