切换顶级元素
Switch through top level elements
我在 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"。
非常感谢您的宝贵时间。
此致
比约恩
不要为此使用 <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']
我在 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"。
非常感谢您的宝贵时间。
此致 比约恩
不要为此使用 <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']