通用映射值 - 模板使用xslt

时间:2014-01-21 11:30:51

标签: xml xslt

例如,我们有这个模板:

<GetRow>
    <CLASS_INTERNAL_NAME>?</CLASS_INTERNAL_NAME>           
    <V_ORG_CODE>?</V_ORG_CODE>          
    <V_START_DATE_ACTIVE>?</V_START_DATE_ACTIVE>            
    <V_END_DATE_ACTIVE>?</V_END_DATE_ACTIVE>            
    <V_START_DATE_UPDATE>?</V_START_DATE_UPDATE>          
    <V_END_DATE_UPDATE>?</V_END_DATE_UPDATE>      
    <V_STATUS_ROW>?</V_STATUS_ROW>
</GetRow>

像这样的DataSource xml:

    <GetRaw>
        <V_START_DATE_UPDATE>${system:lastInvoke}</V_START_DATE_UPDATE>
        <V_END_DATE_UPDATE>22.01.2014</V_END_DATE_UPDATE>
        <V_ORG_CODE>123</V_ORG_CODE>
    </GetRaw>

我想写一个通用的xslt,是什么产生了这个结果:

<GetRow>
    <CLASS_INTERNAL_NAME>?</CLASS_INTERNAL_NAME>           
    <V_ORG_CODE>123</V_ORG_CODE>          
    <V_START_DATE_ACTIVE>${system:lastInvoke}</V_START_DATE_ACTIVE>            
    <V_END_DATE_ACTIVE>22.01.2014</V_END_DATE_ACTIVE>            
    <V_START_DATE_UPDATE>?</V_START_DATE_UPDATE>          
    <V_END_DATE_UPDATE>?</V_END_DATE_UPDATE>      
    <V_STATUS_ROW>?</V_STATUS_ROW>
</GetRow>

我写了这个xslt,但是在创建多个节点时:

<xsl:template match="*">
    <xsl:for-each select="*">
        <xsl:variable name="vNode" select="."/>
        <xsl:variable name="nNode" select="name(.)"/>

        <xsl:for-each select="document('untitled3.xml')/GetRaw/*">

            <xsl:choose>
                <xsl:when test="contains(name(.),$nNode)">
                    <xsl:element name="{$nNode}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:element name="{$nNode}">
                        <xsl:value-of select="$vNode"/>
                    </xsl:element> 
                </xsl:otherwise>
            </xsl:choose>                

        </xsl:for-each>            
    </xsl:for-each>       
</xsl:template>

请帮助我改进它。

2 个答案:

答案 0 :(得分:1)

我会使用模板而不是for-each来构建它,例如:

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

  <xsl:variable name="data" select="document('dataSource.xml')/*/*" />

  <xsl:template match="/*">
    <xsl:copy><xsl:apply-templates select="*" /></xsl:copy>
  <xsl:template>

  <!-- copy the data element, if there is one, and the template one otherwise -->
  <xsl:template match="*">
    <xsl:variable name="dataElt" select="$data[name() = name(current())]" />
    <xsl:choose>
      <xsl:when test="$dataElt">
        <xsl:copy-of select="$dataElt" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

此样式表要求其主要输入文件为模板 XML,并使用document函数从固定文件名加载数据源。如果您希望在数据源上运行样式表并从固定位置加载模板,那么样式表将如下所示:

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

  <xsl:variable name="data" select="/*/*" />

  <xsl:template match="/">
    <xsl:apply-templates select="document('template.xml')/*" />
  </xsl:template>

  <!-- remaining templates for "/*" and "*" are unchanged from before - they
       will still be matching against the template XML file -->

答案 1 :(得分:0)

通过坚持您的示例(不考虑其他事项),请尝试以下模板:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <GetRow>
        <CLASS_INTERNAL_NAME>
            <xsl:choose>
                <xsl:when test="/GetRaw/CLASS_INTERNAL_NAME">
                    <xsl:value-of select="/GetRaw/CLASS_INTERNAL_NAME"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </CLASS_INTERNAL_NAME>           
        <V_ORG_CODE>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_ORG_CODE">
                    <xsl:value-of select="/GetRaw/V_ORG_CODE"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_ORG_CODE>          
        <V_START_DATE_ACTIVE>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_START_DATE_ACTIVE">
                    <xsl:value-of select="/GetRaw/V_START_DATE_ACTIVE"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_START_DATE_ACTIVE>            
        <V_END_DATE_ACTIVE>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_END_DATE_ACTIVE">
                    <xsl:value-of select="/GetRaw/V_END_DATE_ACTIVE"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_END_DATE_ACTIVE>            
        <V_START_DATE_UPDATE>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_START_DATE_UPDATE">
                    <xsl:value-of select="/GetRaw/V_START_DATE_UPDATE"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_START_DATE_UPDATE>          
        <V_END_DATE_UPDATE>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_END_DATE_UPDATE">
                    <xsl:value-of select="/GetRaw/V_END_DATE_UPDATE"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_END_DATE_UPDATE>      
        <V_STATUS_ROW>
            <xsl:choose>
                <xsl:when test="/GetRaw/V_STATUS_ROW">
                    <xsl:value-of select="/GetRaw/V_STATUS_ROW"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'?'"/>
                </xsl:otherwise>
            </xsl:choose>
        </V_STATUS_ROW>
    </GetRow>
</xsl:template>

</xsl:stylesheet>