我有这个XML:
<Root>
<Tag>
<Childlist>
<I>1</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
</Childlist>
<Childlist>
<I>11</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
</Childlist>
</Tag>
</Root>
我希望将其转换为:
<Root>
<Tag>
<Childlist>
<item>
<I>1</I>
<Dlist>
<item>2</item>
<item>3</item>
<item>4</item>
</Dlist>
</item>
<item>
<I>11</I>
<Dlist>
<item>2</item>
<item>3</item>
<item>4</item>
</Dlist>
</item>
</Childlist>
</Tag>
</Root>
使用XSLT。如您所见,第一个XML中的重复标记被替换为标记,列表标记被替换为父标记。
有人可以建议xslt进行此转换吗?
提前致谢。
修改:来自评论。
我遇到this xls的问题。 如果我在Dlist下面添加任何标签,它就会得到 附加到Dlist
还有其他的事情 和以下元素 [来自
Dlist
]
答案 0 :(得分:1)
除了Dimitre的优秀答案,这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="Tag">
<Tag>
<Childlist>
<xsl:apply-templates select="node()[1]"/>
</Childlist>
</Tag>
</xsl:template>
<xsl:template match="*/Dlist[1]">
<xsl:copy>
<xsl:call-template name="makeItem"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Childlist|Dlist" name="makeItem">
<Item>
<xsl:apply-templates select="node()[1]"/>
</Item>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
</xsl:stylesheet>
输出:
<Root>
<Tag>
<Childlist>
<Item>
<I>1</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
</Item>
<Item>
<I>11</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
</Item>
</Childlist>
</Tag>
</Root>
修改:使用此输入:
<Root>
<Tag>
<Childlist>
<I>1</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
<F>1</F>
</Childlist>
<Childlist>
<I>11</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
<F>11</F>
</Childlist>
</Tag>
</Root>
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="Tag">
<Tag>
<Childlist>
<xsl:apply-templates select="node()[1]"/>
</Childlist>
</Tag>
</xsl:template>
<xsl:template match="*/Dlist[last()]" name="makeItem">
<Item>
<xsl:apply-templates select="node()[1]"/>
</Item>
</xsl:template>
<xsl:template match="*/Dlist[1]">
<xsl:copy>
<xsl:call-template name="wrap"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()
[not(self::Dlist)][1]"/>
</xsl:template>
<xsl:template match="Childlist|Dlist" name="wrap">
<xsl:call-template name="makeItem"/>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
</xsl:stylesheet>
输出:
<Root>
<Tag>
<Childlist>
<Item>
<I>1</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
<F>1</F>
</Item>
<Item>
<I>11</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
<F>11</F>
</Item>
</Childlist>
</Tag>
</Root>
注意:这假定Dlist
个元素都是下一个兄弟姐妹。因此,Dlist[1]
会打开新级别,然后将模板应用于下一个没有Dlist
节点,Dlist[last()]
关闭不将模板应用于下一个兄弟级别的级别。
答案 1 :(得分:0)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kDlist" match="Dlist"
use="generate-id((.|preceding-sibling::Dlist)[1])"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[Childlist]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<Childlist>
<xsl:apply-templates/>
</Childlist>
</xsl:copy>
</xsl:template>
<xsl:template match="Childlist|Dlist" name="makeItem">
<Item>
<xsl:apply-templates/>
</Item>
</xsl:template>
<xsl:template match="Dlist[not(preceding-sibling::Dlist)]">
<Dlist>
<xsl:apply-templates select="key('kDlist', generate-id())" mode="copy"/>
</Dlist>
</xsl:template>
<xsl:template match="Dlist" mode="copy">
<xsl:call-template name="makeItem"/>
</xsl:template>
<xsl:template match="Dlist"/>
</xsl:stylesheet>
应用于此XML文档时(原始文本已更正为格式良好):
<Root>
<Tag>
<Childlist>
<I>1</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
</Childlist>
<Childlist>
<I>11</I>
<Dlist>2</Dlist>
<Dlist>3</Dlist>
<Dlist>4</Dlist>
</Childlist>
</Tag>
</Root>
生成想要的正确结果:
<Root>
<Tag>
<Childlist>
<Item>
<I>1</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
</Item>
<Item>
<I>11</I>
<Dlist>
<Item>2</Item>
<Item>3</Item>
<Item>4</Item>
</Dlist>
</Item>
</Childlist>
</Tag>
</Root>