我需要移动相应<sectionid/>
内的<sponsor/>
和<amendment/>
元素。
以下是一个例子:
来自:
<root>
<sectionid>A</sectionid>
<sponsor>john</sponsor>
<sponsor>paul</sponsor>
<amendment>
<id>1</id>
<text>some text</text>
</amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<amendment>
<id>5</id>
<text>some text</text>
</amendment>
<amendment>
<id>4</id>
<text>some text</text>
</amendment>
<sponsor>max</sponsor>
<amendment>
<id>6</id>
<text>some text</text>
</amendment>
<amendment>
<id>7</id>
<text>some text</text>
</amendment>
</root>
为:
<root>
<amendment>
<sectionid>A</sectionid>
<sponsor>john</sponsor>
<sponsor>paul</paul>
<id>1</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>5</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>4</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>max</sponsor>
<id>6</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>max</sponsor>
<id>7</id>
<text>some text</text>
</amendment>
</root>
注1:<section/>
元素适用于下一个<amendments/>
之前的所有<sectionid/>
注意2:<sponsor/>
元素适用于下一个<amendments/>
列表之前的所有<sponsor/>
。
注3://amendment/id
的值不是连续的。
如何使用XSLT 1.0完成此转换。
答案 0 :(得分:1)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:param name="pSectionId"/>
<xsl:param name="pSponsors"/>
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pSectionId" select="$pSectionId"/>
<xsl:with-param name="pSponsors" select="$pSponsors"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sectionid">
<xsl:param name="pSectionId"/>
<xsl:param name="pSponsors"/>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pSectionId" select="."/>
<xsl:with-param name="pSponsors" select="$pSponsors"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sponsor">
<xsl:param name="pSectionId"/>
<xsl:param name="pSponsors"/>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pSectionId" select="$pSectionId"/>
<xsl:with-param name="pSponsors" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sponsor[preceding-sibling::node()[1]/self::sponsor]">
<xsl:param name="pSectionId"/>
<xsl:param name="pSponsors"/>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pSectionId" select="$pSectionId"/>
<xsl:with-param name="pSponsors" select="$pSponsors|."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="amendment">
<xsl:param name="pSectionId"/>
<xsl:param name="pSponsors"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="$pSectionId|$pSponsors"/>
<xsl:apply-templates select="node()[1]"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]">
<xsl:with-param name="pSectionId" select="$pSectionId"/>
<xsl:with-param name="pSponsors" select="$pSponsors"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
输出:
<root>
<amendment>
<sectionid>A</sectionid>
<sponsor>john</sponsor>
<sponsor>paul</sponsor>
<id>1</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>5</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>4</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>max</sponsor>
<id>6</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>max</sponsor>
<id>7</id>
<text>some text</text>
</amendment>
</root>
注意:细粒度遍历。线性复杂性。
修改:新输入样本。
答案 1 :(得分:1)
此转化:
<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="amendment">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="vSectionId"
select="preceding-sibling::sectionid[1]"/>
<xsl:variable name="vprevAmendment"
select="preceding-sibling::amendment[1]"/>
<xsl:apply-templates select="$vSectionId" mode="copy"/>
<xsl:variable name="vsectSponsors"
select="preceding-sibling::sponsor
[generate-id(preceding-sibling::sectionid[1])
=
generate-id($vSectionId)
]"/>
<xsl:variable name="vamdSponsors"
select="preceding-sibling::sponsor
[generate-id(preceding-sibling::amendment[1])
=
generate-id($vprevAmendment)
]"/>
<xsl:apply-templates mode="copy"
select="$vamdSponsors|$vsectSponsors[not($vamdSponsors)]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="sectionid|sponsor"/>
</xsl:stylesheet>
应用于提供的XML文档:
<root>
<sectionid>A</sectionid>
<sponsor>john</sponsor>
<sponsor>paul</sponsor>
<amendment>
<id>1</id>
<text>some text</text>
</amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<amendment>
<id>5</id>
<text>some text</text>
</amendment>
<amendment>
<id>4</id>
<text>some text</text>
</amendment>
<sponsor>max</sponsor>
<amendment>
<id>6</id>
<text>some text</text>
</amendment>
</root>
生成想要的正确结果:
<root>
<amendment>
<sectionid>A</sectionid>
<sponsor>john</sponsor>
<sponsor>paul</sponsor>
<id>1</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>5</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>peter</sponsor>
<id>4</id>
<text>some text</text>
</amendment>
<amendment>
<sectionid>B</sectionid>
<sponsor>max</sponsor>
<id>6</id>
<text>some text</text>
</amendment>
</root>