如何将XML文件中的某些子节点与Parent的一对多关系及其内容移动到父级外部的xml文件的底部。 首先是特定节点,然后可能是2个不同的节点。
在此示例中,我想将所有Child1及其内容移至<Parent>
之外,并将其置于</Parent>
之下且位于<Control> </Control>
之内。
<Controls>
<Parent ID="1" Prop2="kk">
----
<Child1 ID="1" Prop2="kk1">
------
</Child1>
<Child2 ID="1" Prop2="kk2">
------
</Child2>
</Parent>
<Parent ID="2" Prop2="kk4">
----
<Child1 ID="11" Prop2="kk5">
------
</Child1>
<Child2 ID="11" Prop2="kk6">
------
</Child2>
</Parent>
<Parent ID="3" Prop2="kk7">
----
<Child1 ID="111" Prop2="kk8">
------
</Child1>
<Child2 ID="111" Prop2="kk9">
------
</Child2>
</Parent>
</Controls>
预期产出
<MyControls>
<Parent id="1">
----
<Child2 id="1">
------
</Child2>
</Parent>
<Parent id="2">
----
<Child2 id="11">
------
</Child2>
</Parent>
<Parent id="3">
----
<Child2 id="111">
------
</Child2>
</Parent>
<Child1 id="1">
------
</Child1>
<Child1 id="11">
------
</Child1>
<Child1 id="111">
------
</Child1>
</MyControls>
使用过的XSLT
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Child1">
<Child1>
<xsl:apply-templates select="@*[not(self::Child1)]" />
<xsl:apply-templates select="node()[not(self::Child1)]" />
</Child1>
</xsl:template>
答案 0 :(得分:2)
您的样式表是一个开始,但您需要更多例外来阻止Child1
内的Parent
元素被复制。
尝试这样的事情:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Parent">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()[not(self::Child1)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Controls">
<xsl:copy>
<xsl:apply-templates select="Parent"/>
<xsl:apply-templates select="Parent/Child1"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,Parent
会获得特殊复制,其中除了Child1
之外的所有后代都会被复制。在Controls
s之前,Parent
被Child1
明确排序。
在您的(略微修改以修复格式错误)源XML上运行时生成此输出:
<Controls>
<Parent id="1">
----
<Child2 id="1">
------
</Child2>
</Parent>
<Parent id="2">
----
<Child2 id="11">
------
</Child2>
</Parent>
<Parent id="3">
----
<Child2 id="111">
------
</Child2>
</Parent>
<Child1 id="1">
------
</Child1>
<Child1 id="11">
------
</Child1>
<Child1 id="111">
------
</Child1>
</Controls>
基于评论中的请求的新XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Controls">
<MyControls>
<xsl:apply-templates select="@*|node()"/>
<xsl:apply-templates select="Parent/Child1"/>
</MyControls>
</xsl:template>
<xsl:template match="Parent">
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::Child1)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@ID">
<xsl:attribute name="id">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*[not(name()='ID')]"/>
</xsl:stylesheet>