切换顶级元素

时间:2015-10-14 08:41:06

标签: xml xslt xslt-1.0

我在xslt遇到了问题。我的问题是,我在xml中有一行,应该用xsl替换。我想替换一个由informatica本身生成的informatica文件。

首先,这是我的xsl:

  <xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output
  method="xml"
  indent="yes"
  omit-xml-declaration="no"
  media-type="string"
  encoding="ISO-8859-1"
  doctype-system="deftable.dtd"
  /> 
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//AUTOEDIT2[@NAME='%%PARAM']">
        <xsl:choose>
            <xsl:when test="../JOB[@JOBNAME]='FILE_STUFF'">
                <AUTOEDIT2 NAME="%%PARAM" VALUE="*"/>
            </xsl:when>
            <xsl:when test="../JOB[@JOBNAME]='DATA_STUFF'">
                <AUTOEDIT2 NAME="%%PARAM" VALUE="*"/>
            </xsl:when>
            <xsl:when test="../JOB[@JOBNAME]='TANSFER_STUFF'">
                <AUTOEDIT2 NAME="%%PARAM" VALUE="*"/>
            </xsl:when>
            <xsl:otherwise>
                <AUTOEDIT2 NAME="%%PARAM" VALUE="20150910"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
  </xsl:stylesheet>

现在这是我的xml,应该在那里进行替换:

<SOMETREE>
    <JOB JOBNAME="FILE_STUFF">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="not so important, should be overwritten"/>
    </JOB>
    <JOB JOBNAME="DATA_STUFF">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="not so important, should be overwritten"/>
    </JOB>
    <JOB JOBNAME="TANSFER_STUFF">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="not so important, should be overwritten"/>
    </JOB>
    <JOB JOBNAME="OTHER_STUFF">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="not so important, should be overwritten"/>
    </JOB>
</SOMETREE>

所以我想覆盖AUTOEDIT2字段中与JOBNAME相关的值“VALUE”。

非常感谢你的时间。

祝你好运 的Björn

1 个答案:

答案 0 :(得分:1)

不要使用<xsl:choose>。您可以通过模板匹配来完成:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
    <xsl:output encoding="ISO-8859-1" doctype-system="deftable.dtd" /> 

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

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM' and ../@JOBNAME = 'FILE_STUFF']" priority="1">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="*" />
    </xsl:template>

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM' and ../@JOBNAME = 'DATA_STUFF']" priority="1">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="*" />
    </xsl:template>

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM' and ../@JOBNAME = 'TANSFER_STUFF']" priority="1">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="*" />
    </xsl:template>

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM']" priority="0">
        <xsl:copy>20150910</xsl:copy>
    </xsl:template>

</xsl:stylesheet>

请注意显式模板优先级:默认情况下,所有AUTOEDIT2模板都具有相同的优先级(根据XSLT引擎的匹配表达式计算)。设置显式优先级定义哪个模板赢得平局。

前三个模板和最后一个模板中的任何一个都可能出现平局。如果优先级较低,则只有在AUTOEDIT2元素与其他三个元素不匹配时才能选择它。

由于前三个AUTOEDIT2模板的预期结果似乎相同,您可以将它们合并为一个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
    <xsl:output encoding="ISO-8859-1" doctype-system="deftable.dtd" /> 

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

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM' and 
      (
        ../@JOBNAME = 'FILE_STUFF' 
        or ../@JOBNAME = 'DATA_STUFF'
        or ../@JOBNAME = 'TANSFER_STUFF'
      )
    ]" priority="1">
        <AUTOEDIT2 NAME="%%PARAM" VALUE="*" />
    </xsl:template>

    <xsl:template match="AUTOEDIT2[@NAME = '%%PARAM']" priority="0">
        <xsl:copy>20150910</xsl:copy>
    </xsl:template>

</xsl:stylesheet>

放置匹配表达式的另一种方法是:

JOB[
    @JOBNAME = 'FILE_STUFF' or @JOBNAME = 'DATA_STUFF' or @JOBNAME = 'TANSFER_STUFF'
]/AUTOEDIT2[@NAME = '%%PARAM']