生成XSLT以根据源内容将源值结构映射到目标字段

时间:2012-02-29 07:13:38

标签: xslt mapping nested metadata

我有这种格式的xml源列表:

<metadata>
  <metadatum>
    <description>OnEnter</description>
    <value>Hello World</id>
  </metadatum>
  <metadatum>
    <description>OnLeave</description>
    <value>Goodbye World</id>
  </metadatum>
</metadata>

和这样的目标结构:

<friendlyText>
  <onEnter>[Content Here]</onEnter>
  <onLeave>[Content Here]</onLeave>
</friendlyText>

是否可以创建一个XSLT,根据源'描述'将元数据层次结构中的'value'字段映射到正确的目标节点?

我正试图用Altova MapForce完成这项工作;感觉应该有一个允许这个的接口,我只是没找到它。

2 个答案:

答案 0 :(得分:1)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes"/>

  <xsl:template match="metadata">
    <friendlyText>
      <xsl:apply-templates select="metadatum"/>
    </friendlyText>  
  </xsl:template>

  <xsl:template match="metadatum">
    <xsl:element name="{description}">
      <xsl:value-of select="value"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="utf-8"?>
<friendlyText>
  <OnEnter>Hello World</OnEnter>
  <OnLeave>Goodbye World</OnLeave>
</friendlyText>

答案 1 :(得分:0)

此转换是一种通用解决方案,可以与单独的XML文档中的任何“目标结构”一起使用

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vUpper" select=
  "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
 <xsl:variable name="vLower" select=
  "'abcdefghijklmnopqrstuvwxyz'"/>

 <my:target>
  <friendlyText>
    <onEnter>[Content Here]</onEnter>
    <onLeave>[Content Here]</onLeave>
  </friendlyText>
 </my:target>

 <xsl:variable name="vTarget" select="document('')/*/my:target/*"/>

 <xsl:variable name="vMeta" select="/*/metadatum"/>

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

 <xsl:template match="/">
     <xsl:apply-templates select="$vTarget"/>
 </xsl:template>

 <xsl:template match="friendlyText/*/text()">
  <xsl:value-of select=
  "$vMeta[translate(description, $vLower, $vUpper)
        =
          translate(name(current()/..), $vLower, $vUpper)
          ]/value"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档(更正为格式良好):

<metadata>
    <metadatum>
        <description>OnEnter</description>
        <value>Hello World</value>
    </metadatum>
    <metadatum>
        <description>OnLeave</description>
        <value>Goodbye World</value>
    </metadatum>
</metadata>

生成想要的正确结果

<friendlyText xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
   <onEnter>Hello World</onEnter>
   <onLeave>Goodbye World</onLeave>
</friendlyText>

请注意:仅为方便起见,“目标结构”在此处内联。在现实世界中,最好将“目标结构”保存在单独的文件中,并使用document()函数加载它。只有一行:

 <xsl:variable name="vTarget" select="document('')/*/my:target/*"/>

需要更改为:

 <xsl:variable name="vTarget" select="document('someFileUrl')/*"/>