XSLT:使用映射来更改子元素

时间:2016-08-17 23:58:34

标签: xml xslt

我有一个XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <category id="Cat1" owner="Team1">
        <entry id="Ent1" owner="John">
            <title>This is Entry 1</title>
        </entry>
        <entry id="Ent2" owner="Matt">
            <title>This is Entry 2</title>
        </entry>
    </category>
    <category id="Cat2" owner="Team2">
        <entry id="Ent3" owner="Arnold">
            <title>This is Entry 3</title>
        </entry>
        <entry id="Ent4" owner="Jim">
            <title>This is Entry 4</title>
        </entry>
    </category>
 </root>

对于每个ENTRY元素,我想根据其@id属性更改其TITLE子元素的值。我创建了以下XSLT,它首先定义了一个map ...每个map条目的键是我想要更改其标题的元素的@id。每个映射条目的值是我想要的TITLE元素(它是ENTRY的子元素)的值:

<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="*"/>
    <!-- set up the map -->
    <xsl:variable name="map">
        <entry key="Ent1">Here is the first entry</entry>
        <entry key="Ent2">Here is the second entry</entry>
        <entry key="Ent3">Here is the third entry</entry>
        <entry key="Ent4">Here is the fourth entry</entry>
    </xsl:variable>
    <!-- identity transform -->
    <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

    <!-- Problem area: use the key to set the attribute of the correct procedure -->
    <xsl:template match="entry">
        <title><xsl:value-of select="$map/entry[@key = current()/@id]"/></title>
    </xsl:template>
</xsl:stylesheet>

根据我的理解,这是一个两步过程:

  1. 执行身份转换
  2. 创建新模板以更改TITLE元素
  3. 但是这创造了一个奇怪的输出,它用TITLE元素取代了我的整个ENTRY元素......好像所有的一切都被执行了一步太高。

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
       <category id="Cat1">
          <title>Here is the first entry</title>
          <title>Here is the second entry</title>
          <title>Here is the third entry</title>
       </category>
       <category id="Cat2">
          <title>Here is the fourth entry</title>
          <title>Here is the fifth entry</title>
          <title>Here is the sixth entry</title>
       </category>
    </root>
    

    我的地图有什么不对吗?我是否误解了在身份转换后我必须使用的新模板?

1 个答案:

答案 0 :(得分:1)

如果要修改title元素,则模板应与title匹配 - 而不是其父元素entry

<xsl:template match="title">
    <title>
        <xsl:value-of select="$map/entry[@key = current()/../@id]"/>
    </title>
</xsl:template>

或者,您必须在继续entry孩子之前重新创建title的内容:

<xsl:template match="entry">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <title>
            <xsl:value-of select="$map/entry[@key = current()/@id]"/>
        </title>
    </xsl:copy>
</xsl:template>