【问题标题】:Mapping XML values via XSLT通过 XSLT 映射 XML 值
【发布时间】:2012-08-06 15:23:53
【问题描述】:

查看了所有 xslt 映射问题,但似乎无法找到以下具体案例的帮助:

我有一个 xml 文件,例如具有以下值

<rate>
<code>AB</code>
<code>CD</code>
<code>EF</code>
</rate>

这些代码出现在我通过 xslt 输出的 xml 中。 但是,每当 xslt 输出这些特定代码时,它需要首先将它们映射到新值 例如,映射如下:

Code AB -> YZ
Code CD -> WX
Code EF -> QR

请有人告诉我是否以及如何在整个 xslt 中执行此映射,再次记住这些速率代码可以出现在整个 xml 中的各个位置,并且 xslt 所做的不仅仅是这个映射.

谢谢

【问题讨论】:

    标签: xml xslt map


    【解决方案1】:

    使用推送式、基于模板的处理,您应该能够编写模板来进行映射,例如

    <xsl:template match="rate/code[. = 'AB']">
      <xsl:copy>
       <xsl:text>YZ</xsl:text>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="rate/code[. = 'CD']">
      <xsl:copy>
       <xsl:text>WX</xsl:text>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="rate/code[. = 'EF']">
      <xsl:copy>
       <xsl:text>QR</xsl:text>
      </xsl:copy>
    </xsl:template>
    

    然后,如果您确保对任何 rate 父元素执行 apply-templates,例如一个特定的模板作为

    <xsl:template match="rate[code]">
      <xsl:copy>
        <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template>
    

    或者如果您不想更改任何内容,则身份转换模板就足以完成这项工作,例如

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

    我还会考虑在自己的文件中定义映射并从该文件中提取值,至少使用 XSLT 2.0 你可以这样做,例如

    <xsl:param name="mapping-url" select="'mapping.xml'"/>
    <xsl:variable name="mapping-doc" select="document($mapping-url)"/>
    

    文件然后定义的地方,例如

    <mapping>
      <map in="AB" out="YZ"/>
      <map in="CD" out="WX"/>
      <map in="EF" out="QR"/>
    </mapping>
    

    然后你可以使用例如

    <xsl:key name="mk" match="mapping/map" use="@in"/>
    
    
    <xsl:template match="rate/code[key('mk', ., $mapping-doc)]">
      <xsl:copy>
        <xsl:value-of select="key('mk', ., $mapping-doc)/@out"/>
      </xsl:copy>
    </xsl:template>
    

    而不是为需要映射的每个值编写模板。

    【讨论】:

    • 太棒了!我要试试这个!谢谢。
    • 以上不起作用,但我认为这是因为 xml 结构比我上面的示例复杂得多。例如: 元素可能出现在 xml 的根目录或其他分支中。我需要在上面修改什么来处理这个问题?另外我应该补充一点,以这种方式在整个 xslt 中以各种模板输出速率代码.... <value-of select="RATING/ABBREVIATION"></value-of> 我假设我需要将映射合并到其中的每一个实例? (对不起,我是 xslt 的新手)。有什么帮助吗?任何人?谢谢
    • 我建议的代码不假定rate/code 元素在输入树中的任何特定位置。但是,它假定您使用推送样式、基于模板的处理。至于&lt;xsl:value-of select="RATING/ABBREVIATION" /&gt;,它与名为rate 和code 的元素有什么关系?
    • 抱歉造成混淆 - 我在示例中使用了速率/代码,但我的 xml 中的实际元素是等级/缩写。所以我不清楚为什么它不起作用。您提供给我的代码是否需要放在 xslt 中的任何特定位置 - 即是否应该在最后进行映射?
    • 您需要使用&lt;xsl:apply-templates select="RATING/ABBREVIATION"/&gt; 来确保应用我建议的模板来输出值,而不是在RATING 元素的父元素的模板中执行&lt;xsl:value-of select="RATING/ABBREVIATION"/&gt;。这就是 XSLT 中推送样式处理的工作方式,您编写模板进行转换工作并确保通过 apply-templates 处理它们以保持处理或选择要处理的节点。
    猜你喜欢
    • 2021-04-12
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    相关资源
    最近更新 更多