使用 XSL 模板将兄弟节点移动到当前节点

Move sibling node into current node with XSL template

我是 XSL 模板的新手,正在尝试我认为是简单的转换,但我没有取得太大进展。我想改造这个 XML:

<Books>
    <Name>
        <p>Romeo and Juliet</p>
    </Name>
    <Text>
        <p>Two houses...</p>
    </Text>
    <Name>
        <p>Hamlet</p>
    </Name>
    <Text>
        <p>Who's there...</p>
    </Text>
</Books>

对此:

<Books>
    <Book>
        <Title>Romeo and Juliet</Title>
        <Content>
            <p>Two houses...</p>
        </Content>
    </Book>
    <Book>
        <Title>Hamlet</Title>
        <Content>
            <p>Who's there...</p>
        </Content>
    </Book>
</Books>

注意以下变化:

  1. Name 元素及其后面的 Text 元素组合到一个 Book 元素中,并将它们重命名为 TitleContent.
  2. Name 中删除 p 标签,但不从 Text 中删除。

这是我最近的抱歉尝试,但没有用:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <xsl:template match="Name">
        <Book>
            <Title>
                <xsl:copy-of select="."/>
            </Title>
            <Content>
                <xsl:copy select="following-sibling::Text[1]"/>
            </Content>
        </Book>
    </xsl:template>


    <xsl:template name="gettitle" match="p">
        <xsl:value-of select="."/>
    </xsl:template>

</xsl:stylesheet>

如有任何帮助,我们将不胜感激!

如果他们总是成对出现,你为什么不简单地做:

XSLT 1.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:template match="/Books">
    <xsl:copy>
        <xsl:for-each select="Name">
            <Book>
                <Title>
                    <xsl:value-of select="p"/>
                </Title>
                <Content>
                    <xsl:copy-of select="following-sibling::Text[1]/p"/>
                </Content>
            </Book>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

XSLT 2.0 中,您可以:

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

<xsl:template match="/Books">
    <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="Name">
            <Book>
                <Title>
                    <xsl:value-of select="p"/>
                </Title>
                <Content>
                    <xsl:copy-of select="current-group()[self::Text]/p"/>
                </Content>
            </Book>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

这适用于 Name 之后的任意数量的 Text 元素,在 Content 中为每个元素创建一个 p 元素。