2016-07-21 255 views
1

我刚开始学习使用XLS进行XML到XML转换,所以也许这是新手,但似乎无法获得我想要的转换单个XSLT迭代,并且无法找到关于此特定问题的任何内容。
下面是我得到了什么:将子节点复制到其父节点的兄弟节点的子节点

源XML:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    </b2> 
</b> 
<c> 
    <b1>ID#1</b1> 
    <b2_2/> 
</c> 
<!-- b and c nodes keep repeating with the same structure for different b1 IDs --> 
</data> 

我需要做的是,其内容从<c>节点移动<b2_2>节点到特定的子节点<b>节点 - 值为b/b1等于值c/b1
因此,如果他们的父母共享一个具有相同值的特定元素,可以将子节点移动到它的Cousin节点。

期望的结果:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    <b2_2/> 
    </b2> 
</b> 
</data> 

当前XSLT:

<xsl:template match="@* | node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="b"> 
    <xsl:variable name="id1" select="b1" /> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    <xsl:apply-templates select="following-sibling::c[b1=$id1]/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

此代码工作的一部分 - 它会将目标<b2_2>节点目标<b>节点,而清理多余的<c>节点。

我现在得到:

<data> 
<a/> 
<b> 
    <b1>ID#1</b1> 
    <b2> 
    <b2_1/> 
    </b2> 
    <b2_2/> 
</b> 
</data> 

我可以看到如何让所需要的转换中有两个XSLT文件的两个步骤,但我觉得解决方法很简单,表面上。不能指定方向将目标节点放置到它应该位于的子节点上,因此可以在正确的方向上欣赏任何提示。

回答

0

如何:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="b2"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
     <xsl:copy-of select="../following-sibling::c[1]/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

</xsl:stylesheet> 

或者,如果您希望通过b1价值链接:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="c" match="c" use="b1" /> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="b2"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
     <xsl:copy-of select="key('c', ../b1)/b2_2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="c"/> 

</xsl:stylesheet> 
+0

谢谢你,这么迅速的答案!你是对的,我必须通过'b1'值链接节点。对不起,我们并没有澄清它,但是'b2'已经有其他元素而不是'b2_2',并且你的代码在这个过程中清除了它们。我编辑了这个问题,使这一点更加清晰。 – twinchenzo

+0

简易修复 - 请参阅上文。 –

+0

非常感谢Michael,您的回答让我朝着正确的方向前进,并且在研究了'xsl:key'的规则后,我成功实施了您提供的实际数据解决方案。 – twinchenzo

相关问题