如何返回用来自XSLT中另一个子节点的数据修改的子节点?

时间:2019-08-23 17:25:21

标签: xml xslt

我有一个要在XSLT 1.0中转换的xml结构。有一个根节点和两个子节点。我希望转换后的结果输出第一个节点,并且应该使用第二个节点的数据对其进行修改。

我尝试过应用身份转换,但是我不知道如何摆脱根节点。我可以创建第一个节点的副本,但是无法弄清楚如何使用另一个节点的数据对其进行编辑。这是我要实现的示例。 Id = 2的成员应该具有从“人”节点合并的节点。

输入:

<Root>
    <Members>
        <Member>
            <Id>1</Id>
        </Member>
        <Member>
            <Id>2</Id>
        </Member>
    </Members>
    <Persons>
        <Person>
            <Id>2</Id>
            <QAs>
                <QA>
                    <Question>Favourite color</Question>
                    <Answer>Red</Answer>
                </QA>
                <QA>
                    <Question>Best friend</Question>
                    <Answer>Brian</Answer>
                </QA>
            </QAs>
        </Person>
    </Persons>
</Root>

输出:

<Members>
    <Member>
        <Id>1</Id>
    </Member>
    <Member>
        <Id>2</Id>
        <QA>
            <Question>Favourite color</Question>
            <Answer>Red</Answer>
        </QA>
        <QA>
            <Question>Best friend</Question>
            <Answer>Brian</Answer>
        </QA>
    </Member>
</Members>

这是我尝试开始时使用的方法,但我不知道该怎么做:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <!--What to do to get rid of the Root node?-->
    </xsl:copy>
</xsl:template>

<xsl:template match="Members">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <!--What to do to get data from Persons?-->
    </xsl:copy>
</xsl:template>

<xsl:template match="Persons"/>

1 个答案:

答案 0 :(得分:1)

最好使用 key 解决交叉引用。试试:

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:strip-space elements="*"/>

<xsl:key name="person" match="Person" use="Id" />

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

<xsl:template match="/Root">
    <xsl:apply-templates select="Members"/>
</xsl:template>

<xsl:template match="Member">
    <xsl:copy>
        <xsl:apply-templates select="* | key('person', Id)/QAs/QA"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>