Xml 将某些子节点下移到新的孙节点级别
我还发现了关于将节点向上移动到父节点中的其他问题,但我缺少将它们向下移动到新创建节点中的技巧 鉴于:Xml 将某些子节点下移到新的孙节点级别,xml,xslt,Xml,Xslt,我还发现了关于将节点向上移动到父节点中的其他问题,但我缺少将它们向下移动到新创建节点中的技巧 鉴于: <Villain> <Name>Dr Evil</Name> <Age>49</Age> <Like>Money</Like> <Like>Sharks</Like> <Like>Lasers</Like> </Villain>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Villain>
邪恶博士
49
钱
鲨鱼
雷射
我试图用XSLT将其转换为:
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Likes>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Likes>
</Villain>
邪恶博士
49
钱
鲨鱼
雷射
换言之,插入一个新的子节点并将所有名为“Like”的子节点移动到它下面。此转换:
<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()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Like[1]">
<Likes>
<xsl:apply-templates select="../Like" mode="copy"/>
</Likes>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Like"/>
</xsl:stylesheet>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Villain>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Likes>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Likes>
</Villain>
应用于提供的XML文档时:
<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()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Like[1]">
<Likes>
<xsl:apply-templates select="../Like" mode="copy"/>
</Likes>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Like"/>
</xsl:stylesheet>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Villain>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Likes>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Likes>
</Villain>
邪恶博士
49
钱
鲨鱼
雷射
生成所需的正确结果:
<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()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Like[1]">
<Likes>
<xsl:apply-templates select="../Like" mode="copy"/>
</Likes>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Like"/>
</xsl:stylesheet>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Villain>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Likes>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Likes>
</Villain>
邪恶博士
49
钱
鲨鱼
雷射
注意事项:
<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()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Like[1]">
<Likes>
<xsl:apply-templates select="../Like" mode="copy"/>
</Likes>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="Like"/>
</xsl:stylesheet>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Villain>
<Villain>
<Name>Dr Evil</Name>
<Age>49</Age>
<Likes>
<Like>Money</Like>
<Like>Sharks</Like>
<Like>Lasers</Like>
</Likes>
</Villain>
好问题(+1)。请参阅我的答案,以获得一个简短且严格遵循XSLT精神的解决方案。非常好,谢谢!对于其他使用此功能的用户,您的身份模板规则(未显示)中需要有name=“identity”。@DJC:对不起,我对代码格式有问题。现在修复了。@Dimitre,我想说的是,我喜欢你在身份模板上添加
name=“identity”
。它使代码更易于阅读。我以前没见过。。。但现在我看到@DJC的评论,这意味着name=“identity”
是必需的。嗯?我从来都不知道它是必需的。@LarsH:通常标识模板不需要名称=“标识
。也许你只是意外地忘记了在Dimitre的代码中你按名称调用这个模板,我相信这是@DJC评论的唯一原因。不过,这是一个很好的问题和答案+1@jasso:谢谢,现在我看到Dimitre在mode=“copy”模板中按名称调用它。(在这里,我认为他只是一个“有文化的程序员”。:-)我只想到了另一种方式,即从默认模板调用/应用标识模板,它不需要名称。