TIA为您提供帮助。我还在学习XSLT,所以请随时告诉我我已经提出的应该以不同的方式完成。
我正在尝试处理以下XML并根据一些简单的条件插入<newtag>
的真值或假值。
<?xml version="1.0" encoding="UTF-8"?>
<FILE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEADER>
<LINE>
<LINENO>1</LINENO>
<DOLLARS>100</DOLLARS>
</LINE>
<LINE>
<LINENO>2</LINENO>
<DOLLARS>100</DOLLARS>
<REASON>
<CODE>1</CODE>
</REASON>
</LINE>
<LINE>
<LINENO>3</LINENO>
<DOLLARS>0</DOLLARS>
<REASON>
<CODE>99</CODE>
</REASON>
</LINE>
<LINE>
<LINENO>4</LINENO>
<DOLLARS>0</DOLLARS>
<REASON>
<CODE>99</CODE>
<CODE>1</CODE>
</REASON>
</LINE>
</HEADER>
</FILE>
如果DOLLARS&gt; 0插入<newtag>false</newtag>
如果DOLLARS = 0且CODE位于值列表中,则插入<newtag>true</newtag>
否则插入<newtag>false</newtag>
我的问题是有两个(或更多)CODE标记作为DOLLARS标记的兄弟。
这是我到目前为止的XSLT。
<?xml version='1.0' ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="xml"
version="1.0"
encoding="UTF-8"
indent="yes"
omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<!-- global template to copy everything that doesn't match the other templates -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Find the DOLLARS tag for every line -->
<xsl:template match="DOLLARS">
<xsl:choose>
<xsl:when test="number(../DOLLARS) > 0">
<xsl:copy-of select="."/>
<newtag>false</newtag>
</xsl:when>
<xsl:when test="contains('-1-2-3-4-5-6-', concat('-', ../CODE, '-'))">
<xsl:copy-of select="."/>
<newtag>true</newtag>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
<newtag>false</newtag>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我知道问题是包含测试只是查找/测试第一个CODE,但我不知道如何测试它们来测试两个CODE标记,如果任何一个CODE是匹配的话,给我一个真实的。 / p>
大卫
答案 0 :(得分:1)
干得好。我希望看到XSLT新用户使用xsl:for-each
之外的东西: - )
您似乎只需要为DOLLARS = 0
添加测试,并将contains()
移到谓词中。
您还可以通过删除xsl:choose
的测试来简化DOLLARS > 0
,因为结果与xsl:otherwise
相同。您也可以将xsl:copy-of
移出xsl:choose
。
示例...
<xsl:template match="DOLLARS">
<xsl:copy-of select="."/>
<xsl:choose>
<xsl:when test=".=0 and ../REASON/CODE[contains('-1-2-3-4-5-6-', concat('-', ., '-'))]">
<newtag>true</newtag>
</xsl:when>
<xsl:otherwise>
<newtag>false</newtag>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
另一种选择是将其拆分为两个单独的模板,而不是使用xsl:choose
...
<xsl:template match="LINE[REASON/CODE[contains('-1-2-3-4-5-6-', concat('-', ., '-'))]]/DOLLARS[.=0]">
<xsl:copy-of select="."/>
<newtag>true</newtag>
</xsl:template>
<xsl:template match="DOLLARS">
<xsl:copy-of select="."/>
<newtag>false</newtag>
</xsl:template>
答案 1 :(得分:1)
如果DOLLARS&gt; 0插入
<newtag>false</newtag>
如果DOLLARS = 0且CODE在值列表中插入 ``真
否则插入
<newtag>false</newtag>
我相信这可以改写为:
1.插入<newtag>
元素
2.如果DOLLARS = 0且CODE在值列表中。然后让<newtag>
的值为真;否则是假的。
考虑以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="valid-codes">
<code>1</code>
<code>2</code>
<code>3</code>
<code>4</code>
<code>5</code>
<code>6</code>
</xsl:variable>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LINE">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<newtag>
<xsl:value-of select="DOLLARS=0 and REASON/CODE=exsl:node-set($valid-codes)/code"/>
</newtag>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<FILE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEADER>
<LINE>
<LINENO>1</LINENO>
<DOLLARS>100</DOLLARS>
<newtag>false</newtag>
</LINE>
<LINE>
<LINENO>2</LINENO>
<DOLLARS>100</DOLLARS>
<REASON>
<CODE>1</CODE>
</REASON>
<newtag>false</newtag>
</LINE>
<LINE>
<LINENO>3</LINENO>
<DOLLARS>0</DOLLARS>
<REASON>
<CODE>99</CODE>
</REASON>
<newtag>false</newtag>
</LINE>
<LINE>
<LINENO>4</LINENO>
<DOLLARS>0</DOLLARS>
<REASON>
<CODE>99</CODE>
<CODE>1</CODE>
</REASON>
<newtag>true</newtag>
</LINE>
</HEADER>
</FILE>