我正在使用Identity Transformation将XML转换为另一个,并且在此期间,基于我想要在新列表中标记几个节点的条件。
假设,我有一个XML:
<点头>
< A>将< / A>
&LT b取代; B< / B个
&LT c取代;< p为H. P1< / P>< / c取代;
&LT c取代;< p为H. P2< / P>< / c取代;
&LT c取代;< p为H. P3< / P>< / c取代;
&LT c取代;< p为H. P4< / P>< / c取代;
< /点头>
从这个XML中,我想将'nod'的名称更新为'newnod'并为元素'c'创建一个有序列表;所以输出如下:
< newnod>
< A>将< / A>
&LT b取代; B< / B个
< orderedlist>
<列表项>< p为H. P1< / P>< /列表项>
<列表项>< p为H. P2< / P>< /列表项>
<列表项>< p为H. P3< / P>< /列表项>
<列表项>< p为H. P4< / P>< /列表项>
< / orderedlist>
< / newnod>
有人可以告诉我怎么做。
谢谢!!!
答案 0 :(得分:1)
这会为您的示例生成所需的输出:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/nod">
<newnod>
<xsl:copy-of select="*[not( self::c )]"/>
<orderedlist>
<xsl:apply-templates select="c">
<xsl:sort/>
</xsl:apply-templates>
</orderedlist>
</newnod>
</xsl:template>
<xsl:template match="nod/c">
<listitem>
<xsl:copy-of select="node()"/>
</listitem>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,您可能需要对实际输入进行一些调整。例如,排序的细节。或a
,b
和c
的序列。并将所有c
混为一谈?但它适用于您的样本。
答案 1 :(得分:1)
这是一个真正的“推式”解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/nod">
<newnod>
<xsl:apply-templates select="node()|@*"/>
</newnod>
</xsl:template>
<xsl:template match="c[1]">
<orderedlist>
<xsl:apply-templates mode="wrap"
select=".|following-sibling::c"/>
</orderedlist>
</xsl:template>
<xsl:template match="c" mode="wrap">
<listitem>
<xsl:apply-templates/>
</listitem>
</xsl:template>
<xsl:template match="c"/>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<nod>
<a>A</a>
<b>B</b>
<c><p>p1</p></c>
<c><p>p2</p></c>
<c><p>p3</p></c>
<c><p>p4</p></c>
</nod>
产生了想要的正确结果:
<newnod>
<a>A</a>
<b>B</b>
<orderedlist>
<listitem>
<p>p1</p>
</listitem>
<listitem>
<p>p2</p>
</listitem>
<listitem>
<p>p3</p>
</listitem>
<listitem>
<p>p4</p>
</listitem>
</orderedlist>
</newnod>
答案 2 :(得分:0)
您可以使用以下内容:
<xsl:template match="nod">
<newnod>
<xsl:copy-of select="a"/>
<xsl:copy-of select="b"/>
<orderedlist>
<xsl:for-each select="c">
<listitem><p><xsl:value-of select="."/></p></listitem>
</xsl:for-each>
</orderedlist>
</newnod>
</xsl:template>
答案 3 :(得分:0)
其他方法是遍历以下轴:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="nod">
<newnod>
<xsl:apply-templates select="node()[1]|@*"/>
</newnod>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="c">
<orderedlist>
<xsl:call-template name="wrap"/>
</orderedlist>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="search"/>
</xsl:template>
<xsl:template match="c" name="wrap" mode="wrap">
<listitem>
<xsl:apply-templates select="node()[1]|@*"/>
</listitem>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="wrap"/>
</xsl:template>
<xsl:template match="node()" mode="wrap"/>
<xsl:template match="c" mode="search">
<xsl:apply-templates select="following-sibling::node()[1]"
mode="search"/>
</xsl:template>
<xsl:template match="node()" mode="search">
<xsl:apply-templates select="."/>
</xsl:template>
</xsl:stylesheet>
或更短(更“推式”):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="nod">
<newnod>
<xsl:apply-templates select="node()[1]|@*"/>
</newnod>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="c">
<orderedlist>
<xsl:call-template name="wrap"/>
</orderedlist>
<xsl:apply-templates select="following-sibling::node()
[not(self::c)][1]"/>
</xsl:template>
<xsl:template match="c" name="wrap" mode="wrap">
<listitem>
<xsl:apply-templates select="node()[1]|@*"/>
</listitem>
<xsl:apply-templates select="following-sibling::node()[1]
/self::c"
mode="wrap"/>
</xsl:template>
</xsl:stylesheet>
两个输出:
<newnod>
<a>A</a>
<b>B</b>
<orderedlist>
<listitem>
<p>p1</p>
</listitem>
<listitem>
<p>p2</p>
</listitem>
<listitem>
<p>p3</p>
</listitem>
<listitem>
<p>p4</p>
</listitem>
</orderedlist>
</newnod>
注意:即使使用XSLT 2.0,使用此模式也可以更好地表达一些复杂的序列处理。