使用xslt重命名一批值



我们有一个使用xml保存程序配置的程序。有人决定重命名我们数据库中的几个值,这些重命名现在也应该在我们客户的配置中向后兼容。

配置示例

<configuration>
    <fruitToEat>yellow_curved_thing</fruitToEat> <!-- should now become banana -->
</configuration>

一个简单的匹配将是(没有测试,只是一个例子):

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

但这只是一个例子,我想做150次。

是否有可能使xsl读取一个简单的文本文件或ini文件,告诉我150个匹配应该如何相似?

<xsl:template>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <!-- recreate this template 150 times from an ini file or something -->
  <xsl:template match"/configuration/fruitToEat/text()[.='yellow_curved_thing']">
    <xsl:text>banana</xsl:text>
  </xsl:template>
</xsl:template>

我的映射文件的一个例子可以很简单:

yellow_curved_thing = banana
round_thing = tomato
round_dotted = strawberry

我只需要一个小的xslt告诉我:

<xsl:template>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <!-- recreate this template 150 times from an ini file or something -->
  <xsl:template match"/configuration/fruitToEat/text()[.=$fileRow0]">
    <xsl:text>$fileRow1</xsl:text>
  </xsl:template>
</xsl:template>

所以即使我认为幕后有更多的复杂性,这可能会有一点帮助。使用xlst有一些可能做到这一点。从长远来看,哪种方法最好取决于现实生活中的复杂性,以及你需要多长时间处理不同的"映射"信息。

对于您的简单示例,您可以将"映射"信息放入xml文件中。这可以通过一些脚本形式的ini文件来完成。

<mappings>
    <mapping name="fruitToEat" >
        <map  from="yellow_curved_thing" to="banana"  />
        <map  from="round_thing" to="tomato"  />
        <map  from="round_dotted" to="strawberry"  />
    </mapping>
</mappings>

你可以有一个模板,利用这个映射信息:

<xsl:variable name="fruitMapping"
             select="document('fruitmapping.xml')//mapping[@name='fruitToEat']" />
    <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
    <xsl:template match="/configuration/fruitToEat/text()"  >
        <!-- find the entry in "ini file" -->
        <xsl:variable name ="map" select="$fruitMapping/map[@from = current()]" />
        <xsl:choose>
            <xsl:when test="$map" >
                <xsl:value-of select="$map/@to"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

但如果这是一个一次性的工作,我会实现这个"映射"直接一个模板。这样的:

<xsl:template match="/configuration/fruitToEat/text()" >
    <xsl:choose>
        <xsl:when test=".='yellow_curved_thing'" >banana</xsl:when>
        <xsl:when test=".='round_thing'" >tomato</xsl:when>
        <xsl:when test=".='round_dotted'" >strawberry</xsl:when>
        <xsl:otherwise>
            <xsl:copy />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

似乎您想要在配置文件(也是XML文档)的基础上创建动态XSLT。看一下这个例子:

configuration.xml

    <p>
  <configuration>
    <fruitToEat>yellow_curved_thing</fruitToEat>
    <mapped>banana</mapped>
  </configuration>
  <configuration>
    <fruitToEat>round_thing</fruitToEat>
    <mapped>tomato</mapped>
  </configuration>
</p>
XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <xsl:element name="xsl:stylesheet">
      <xsl:attribute name="version">
        <xsl:text>1.0</xsl:text>
      </xsl:attribute>
      <xsl:element name="xsl:template">
        <xsl:attribute name="match">
          <xsl:text>node()|@*</xsl:text>
        </xsl:attribute>
        <xsl:element name="xsl:copy">
          <xsl:element name="xsl:apply-templates">
            <xsl:attribute name="select">
              <xsl:text>node()|@*</xsl:text>
            </xsl:attribute>
          </xsl:element>
        </xsl:element>
      </xsl:element>
      <xsl:for-each select="//configuration">
        <xsl:element name="xsl:template">
          <xsl:attribute name="match">
            <xsl:text>configuration/fruitToEat/text()[.=</xsl:text>
            <xsl:text>'</xsl:text>
            <xsl:value-of select="fruitToEat"/>
            <xsl:text>']</xsl:text>
          </xsl:attribute>
          <xsl:element name="xsl:text">
              <xsl:value-of select="mapped"/>
          </xsl:element>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>
输出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
   <xsl:template match="configuration/fruitToEat/text()[.='yellow_curved_thing']">
      <xsl:text>banana</xsl:text>
   </xsl:template>
   <xsl:template match="configuration/fruitToEat/text()[.='round_thing']">
      <xsl:text>tomato</xsl:text>
   </xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新