我需要使用xslt转换XML。
逻辑:
如果父级具有不同的子地址,则拆分父级,并使用父级名称附加序列号。还需要孩子的行号。 这里我们可能有多个父节点,每个父节点可能有更多的子节点。
我已经尝试了很多方法来实现这一点,并且我坚持在foreach中生成序列号。所以任何人都可以尝试并为此提供解决方案。
源XML如下:
<Data>
<Parent>
<Name>P1</Name>
<Child>
<Name>CName1</Name>
<Address>Address1</Address>
</Child>
<Child>
<Name>CName2</Name>
<Address>Address2</Address>
</Child>
<Child>
<Name>CName3</Name>
<Address>Address1</Address>
</Child>
</Parent>
<Parent>
<Name>P2</Name>
<Child>
<Name>CName1</Name>
<Address>Address1</Address>
</Child>
</Parent>
</Data>
目标XML应如下所示:
<Data>
<Parent>
<Name>P1_1</Name>
<Address>Address1</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName1</Name>
</Child>
<Child>
<LineNumber>2</LineNumber>
<Name>CName3</Name>
</Child>
</Parent>
<Parent>
<Name>P1_2</Name>
<Address>Address2</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName2</Name>
</Child>
</Parent>
<Parent>
<Name>P2_1</Name>
<Address>Address1</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName1</Name>
</Child>
</Parent>
</Data>
答案 0 :(得分:3)
此XSLT 1.0转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kAddress" match="Child" use="concat(generate-id(..), '|', Address)" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Parent">
<xsl:variable name="parent" select="." />
<xsl:for-each select="Child[
generate-id()
=
generate-id(key('kAddress', concat(generate-id($parent), '|', Address))[1])
]">
<Parent>
<Name><xsl:value-of select="concat(../Name, '_', position())" /></Name>
<xsl:copy-of select="Address" />
<xsl:apply-templates select="
key('kAddress', concat(generate-id($parent), '|', Address))
" />
</Parent>
</xsl:for-each>
</xsl:template>
<xsl:template match="Child">
<xsl:copy>
<xsl:copy-of select="@*" />
<LineNumber><xsl:value-of select="position()" /></LineNumber>
<xsl:apply-templates select="node()[not(self::Address)]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
为您的样本生成以下输出:
<Data>
<Parent>
<Name>P1_1</Name>
<Address>Address1</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName1</Name>
</Child>
<Child>
<LineNumber>2</LineNumber>
<Name>CName3</Name>
</Child>
</Parent>
<Parent>
<Name>P1_2</Name>
<Address>Address2</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName2</Name>
</Child>
</Parent>
<Parent>
<Name>P2_1</Name>
<Address>Address1</Address>
<Child>
<LineNumber>1</LineNumber>
<Name>CName1</Name>
</Child>
</Parent>
</Data>