以不同的顺序合并XML

时间:2013-05-20 08:21:03

标签: xml xslt

我知道在这个主题上还有其他问题,但我正在寻找的不是那里。

我想要做的是组合2个XML文件,但不能完全组合一个XML文件。

例如我的第一个xml文件是game.xml:

<forSale>
<game>
    <title>Mass Effect 3</title>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>03</mm>
        <dd>06</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>X360</platform>
    </platforms>
</game>
<game>
    <title>Borderlands 2</title>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>09</mm>
        <dd>18</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>PC</platform>
    </platforms>
</game>

我的第二个xml文件reviews.xml

<reviews>
<game>
    <title>Mass Effect 3</title>
    <review>
        <critic>Kevin VanOrd</critic>
        <pros>
            <pro><![CDATA[Fantastic, moving story that balances plot and character]]></pro>
        </pros>
        <cons>
            <con><![CDATA[Some glitches and bugs]]></con>
        </cons>
    </review>
</game>

<game>
    <title>Borderlands 2</title>
    <review>
        <critic>Chris Watters</critic>
        <pros>
            <pro><![CDATA[A ton of great mission writing and dialogue]]></pro>
        </pros>
        <cons>
            <con><![CDATA[Spoken messages sometimes interrupt each other]]></con>
        </cons>
    </review>
</game>

我希望我生成的主XML就像这样:

<forSale>
<game>
    <title>Mass Effect 3</title>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>03</mm>
        <dd>06</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>X360</platform>
    </platforms>
    <review>
        <critic>Kevin VanOrd</critic>
        <synopsis>
            Mass Effect 3 is a remarkably satisfying conclusion to a beloved trilogy, and a poignant and memorable role-playing action game in its own right.
        </synopsis>
        <pros>
            <pro>Fantastic, moving story that balances plot and character</pro>
        </pros>
        <cons>
            <con>Some glitches and bugs</con>
        </cons>
    </review>
</game>
<game>
    <title>Borderlands 2</title>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>09</mm>
        <dd>18</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>PC</platform>
    </platforms>
    <review>
        <critic>Chris Watters</critic>
        <synopsis>
            Stellar writing and a host of small improvements help Borderlands 2 stand tall on the shoulders of its predecessor.
        </synopsis>
        <pros>
            <pro>A ton of great mission writing and dialogue</pro>
        </pros>
        <cons>
            <con>Spoken messages sometimes interrupt each other</con>
        </cons>
    </review>
</game>

我尝试了这段代码,但它首先输出了游戏,然后是评论

<xsl:template match="/forSale">
<xsl:copy>
    <xsl:apply-templates select="game"/>
    <xsl:apply-templates select="document('reviews.xml')/reviews/game/review"/>
    </xsl:copy>
</xsl:template>
<xsl:template match =" @* | node()">
<xsl:copy>
  <xsl:apply-templates select="@* | node() | text()"/>
</xsl:copy>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

这是因为这一行...

<xsl:apply-templates select="document('reviews.xml')/reviews/game/review"/>

独立于您选择游戏的上一行,因此将复制所有游戏,而不仅仅是特定行。

您需要做的是将此行添加到与游戏元素匹配的模板中,并将其修改为仅输出所选游戏

<xsl:apply-templates select="document('reviews.xml')/reviews/game[title=current()/title]/review"/>

试试这个XSLT

<xsl:template match="/forSale">
   <xsl:copy>
       <xsl:apply-templates select="game"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="game">
   <xsl:copy>
       <xsl:apply-templates select="@* | node() | text()"/>
       <xsl:apply-templates select="document('reviews.xml')/reviews/game[title=current()/title]/review"/>
   </xsl:copy>
</xsl:template>

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