XSLT映射元素名称

时间:2013-07-09 08:18:27

标签: xslt map element

我想编写一个XSLT样式表,它通过一些映射规则映射元素名称。为了让样式表可以为经验较少的用户自定义,我想在样式表中单独存储地图:

<mr:mapping-rules>
    <field src="field1" dest="field1337" />
    <field src="field2" dest="field2" />
    <field src="field3" dest="field3" />
</mr:mapping-rules>

以下是一些示例输入数据:

<Record>
    <field1>123</field1>
    <field2>asd</field2>
    <field3>456</field3>
</Record>

预期结果是:

<Record>
    <field1337>123</field1337>
    <field2>asd</field2>
    <field3>456</field3>
</Record>

如果有人能给我一个暗示模板必须是什么样子的话会很好。

2 个答案:

答案 0 :(得分:1)

根据我的评论,这是一个建议。我写了一个样式表,采用

形式的映射文件
<mr:mapping-rules xmlns:mr="http://example.com/mr">
  <context pattern="Record">
    <field src="field1" dest="field1337" />
  </context>
</mr:mapping-rules>

的形式生成样式表
<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="Record/field1">
      <xsl:element name="field1337">
         <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
   </xsl:template>

</xsl:stylesheet>

创建上述样式表作为其输出的样式表是

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mr="http://example.com/mr"
  xmlns:oxsl="http://example.com/xsl"
  exclude-result-prefixes="oxsl mr">

<xsl:namespace-alias stylesheet-prefix="oxsl" result-prefix="xsl"/>

<xsl:output indent="yes"/>

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

<xsl:template match="mr:mapping-rules/context/field">
  <oxsl:template match="{../@pattern}/{@src}">
    <oxsl:element name="{@dest}">
      <oxsl:apply-templates select="@* | node()"/>
    </oxsl:element>
  </oxsl:template>
</xsl:template>

</xsl:stylesheet>

然后,您可以在

之类的输入上运行生成的样式表
<Root>
  <Record-List>
    <Record>
      <field1>foo</field1>
      <field2>bar</field2>
      <field3>baz</field3>
    </Record>
  </Record-List>
</Root>

并输出

<Root>
  <Record-List>
    <Record>
      <field1337>foo</field1337>
      <field2>bar</field2>
      <field3>baz</field3>
    </Record>
  </Record-List>
</Root>

当然,映射文件可以根据您的需要进行调整,我主要尝试显示一个样本,从映射文件生成第二个样式表,然后应用于输入样本。

答案 1 :(得分:1)

Martin的解决方案很好,因为这种方法非常强大且可扩展,但也可以更直接地解决问题:

<xsl:key name="mappings" match="mr:mapping-rules/field" use="@src"/>

<xsl:template match="*">
  <xsl:element name="{(key('mappings', name())/@dest, name())[1]}">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  <xsl:element>
</xsl:template>