如何使用XSL在特定子节点级别添加新元素?

时间:2011-10-25 00:05:49

标签: xml xslt

我正在努力帮助一位朋友解决计算机课带回家的问答。我有一个简单的XML文件,如下所示,它定义了我在架子上拥有的DVD标题......

<Inventory>
    <DVD>
        <Name>Captain America</Name>
    </DVD>
    <DVD>
        <Name>Green Lantern</Name>
    </DVD>
    <DVD>
        <Name>Thor</Name>
    </DVD>
</Inventory>

让我们说“美国队长”和“雷神”都被检查出来,而“绿灯侠”仍然可用。我想将上面的XML文件转换为以下XML ...

<Inventory>
    <DVD>
        <Name>Captain America</Name>
        <Status>Checked-Out</Status>
    </DVD>
    <DVD>
        <Name>Green Lantern</Name>
        <Status>Available</Status>
    </DVD>
    <DVD>
        <Name>Thor</Name>
        <Status>Checked-Out</Status>
    </DVD>
</Inventory>

有人可以分享如何利用XSL将Status元素添加到每个节点吗?我只有下面的代码片段,但它为所有节点复制相同的元素。

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

<xsl:template match="DVD">
    <xsl:copy>
        <xsl:copy-of select="@*|node()"/>
        <Status>Checked-Out</Status>
    </xsl:copy>
</xsl:template>

非常感谢你......

1 个答案:

答案 0 :(得分:4)

您可以使用xsl:param将已签出的DVD的名称传递给您的XSL,并根据该名称添加<status>。通过使用xsl:param,您可以从命令行传递值。

这是一个XSLT 2.0示例,其中DVD名称在xsl:param中以管道分隔。我在tokenize()中使用xsl:template match,以便这些DVD获得“已检出”状态。所有其他DVD都将获得“可用”状态。

XSLT 2.0样式表:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="checkedOut" select="'Captain America|Thor'"/>

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

  <xsl:template match="DVD[Name=tokenize($checkedOut,'\|')]">
    <xsl:copy>
      <xsl:apply-templates/>
      <status>Checked-Out</status>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="DVD">
    <xsl:copy>
      <xsl:apply-templates/>
      <status>Available</status>
    </xsl:copy>
  </xsl:template>  

</xsl:stylesheet>

应用于您的示例XML生成以下输出:

<Inventory>
   <DVD>
      <Name>Captain America</Name>
      <status>Checked-Out</status>
   </DVD>
   <DVD>
      <Name>Green Lantern</Name>
      <status>Available</status>
   </DVD>
   <DVD>
      <Name>Thor</Name>
      <status>Checked-Out</status>
   </DVD>
</Inventory>

希望这有帮助。