0

我想编写一个 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>

如果有人可以给我一个提示模板的外观,那就太好了。

4

2 回答 2

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>
于 2013-07-09T10:34:22.283 回答
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>

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

于 2013-07-09T09:34:25.413 回答