现有格式是
<A>
<B>
<C>hello</C>
<C>how</C>
<C>are</C>
<C>you</C>
</B>
</A>
我想把它变成这样的东西
<start>
<A>
<B>
<tag1> hello </tag1>
<tag2> hello </tag2>
</B>
</A>
<A>
<B>
<tag1> are </tag1>
<tag2> you </tag2>
</B>
</A>
</start>
现在,此<C>
标记可以多次出现,并且对于每个2 <C>
个标记标记一个具有相同标记名称的新<A> </A>
标记(请参阅tag1和tag2名称相同)在两种情况下都应该创建。整个过程是动态的。
我有一个类似于此的
动态XML结构<LSR_RESP>
<HDR>
<ORD>AAAAA</ORD>
<ORD>BBBBB</ORD>
<ORD>CCCCC</ORD>
<ORD>DDDDD</ORD>
<ORD>EEEEE</ORD>
<ORD>FFFFF</ORD>
<ORD>GGGGG</ORD>
<ORD>RRRRR</ORD>
<ORD>KKKKK</ORD>
</HDR>
</LSR_RESP>
我想通过XSLT将其转换为类似的东西
<entity>
<r>
<c>
<f ID="OrderNumber1">AAAAA</f>
<f ID="OrderNumber2">BBBBB</f>
<f ID="OrderNumber3">CCCCC</f>
<f ID="OrderNumber4">DDDDD</f>
<f ID="OrderNumber5">EEEEE</f>
<f ID="OrderNumber6">FFFFF</f>
<f ID="OrderNumber7">GGGGG</f>
</c>
</r>
<r>
<c>
<f ID="OrderNumber1">RRRRR</f>
<f ID="OrderNumber2">KKKKK</f>
</c>
</r>
</entity>
现在您可以看到上面的每个行标记是通过获取7个组中的标记值来生成的。 并且新标签的名称也将以7个为一组重新组合,如“OrderNumber1”到“OrderNumber7”。 该字段可以出现多次,但新结构将以7个为一组形成。
与上面的示例一样,它们是9个标签,因此它形成了2个组中的一个,其中7个离开(9-7),即下一组的2个标签,因此在下一组中,您只能看到OrderNumber1和OrderNumber2。 如果有10个标签,它将是一组7,然后是另一组3。 如果有15个标签,它将是两组7,然后是另一组1。
答案 0 :(得分:3)
最简单的方法(XSLT 1.0足够了):
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<start>
<xsl:apply-templates select="
A/B/C[position() mod 2 = 1 and following-sibling::C]"
/>
</start>
</xsl:template>
<xsl:template match="C">
<A>
<B>
<tag1>
<xsl:value-of select="text()" />
</tag1>
<tag2>
<xsl:value-of select="following-sibling::C[1]/text()" />
</tag2>
</B>
</A>
</xsl:template>
</xsl:stylesheet>
也可能,由于使用单独的模板和<xsl:copy>
/ <xsl:copy-of>
而可能更灵活:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<start>
<xsl:for-each select="
A/B/C[position() mod 2 = 1 and following-sibling::C]
">
<xsl:apply-templates select="ancestor::A">
<xsl:with-param name="C" select="." />
</xsl:apply-templates>
</xsl:for-each>
</start>
</xsl:template>
<xsl:template match="A">
<xsl:param name="C" />
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="B">
<xsl:with-param name="C" select="$C" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="B">
<xsl:param name="C" />
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="$C" />
</xsl:copy>
</xsl:template>
<xsl:template match="C">
<tag1>
<xsl:value-of select="text()" />
</tag1>
<tag2>
<xsl:value-of select="following-sibling::C[1]/text()" />
</tag2>
</xsl:template>
</xsl:stylesheet>
但话说回来,也许这过于复杂,取决于你的实际数据。关键点是只选择有趣的<C>
节点(奇数位置的节点)并围绕它们构建其余的转换。
两个模板都会产生:
<start>
<A>
<B>
<tag1>hello</tag1>
<tag2>how</tag2>
</B>
</A>
<A>
<B>
<tag1>are</tag1>
<tag2>you</tag2>
</B>
</A>
</start>