我需要一些XSLT语法方面的帮助。这是我的场景,我有一个XML文件,需要转换为XML文件的不同外观,我有几个部分,如果特定节点集不包含任何值,则不应处理整个部分。
以下是XML的示例:
<Dates>
<Date>
<VALUE1></VALUE1>
<VALUE2></VALUE2>
<VALUE3></VALUE3>
<VALUE4></VALUE4>
<VALUE5>3333</VALUE5>
</Date>
<Date>
<VALUE1>AAAA</VALUE1>
<VALUE2></VALUE2>
<VALUE3>JJJJ</VALUE3>
<VALUE4></VALUE4>
<VALUE5>12345</VALUE5>
</Date>
</Dates>
这是我的XSLT,if语句不能正常工作
<xsl:for-each select="Level1/Level2/Level3">
<xsl:if test="@VALUE1!=''">
<MyDates>
<value_1>
<xsl:value-of select="VALUE1"/>
</value_1>
<value_2>
<xsl:value-of select="VALUE2"/>
</value_2>
<value_3>
<xsl:value-of select="VALUE3"/>
</value_3>
<value_4>
<xsl:value-of select="VALUE4"/>
</value_4>
</MyDates>
</xsl:if>
</xsl:for-each>
因此,您可以看到我基本上希望所有节点(VALUE1,VALUE2,VALUE3等)都有值,否则不处理并转到下一部分
(如果你看不到XML的想法,我也做了一个屏幕截图)
答案 0 :(得分:12)
您正在尝试匹配文档中不存在的名称为“Level1”,“Level2”等的xml元素。然后,您正在寻找最后一个元素的VALUE1属性。
我想你想要这样的东西:
<xsl:for-each select="Dates">
<MyDates>
<xsl:for-each select="Date">
<xsl:if test="not(*[.=''])">
<MyDate>
<value_1>
<xsl:value-of select="VALUE1"/>
</value_1>
<value_2>
<xsl:value-of select="VALUE2"/>
</value_2>
<value_3>
<xsl:value-of select="VALUE3"/>
</value_3>
<value_4>
<xsl:value-of select="VALUE4"/>
</value_4>
</MyDate>
</xsl:if>
</xsl:for-each>
</MyDates>
</xsl:for-each>
只要相应Date元素中的每个值都不为空,这将添加一个新的MyDate元素。
它做的是
答案 1 :(得分:3)
你还没有很好地定义“节点有价值”是什么意思。
最有可能的是,您会考虑一个元素,它只有一个空格的文本子元素,没有值。 在这种情况下,下面是一个解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="Date[not(*[not(normalize-space())])]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
如果“日期”甚至包含一个没有内容或只有空格的子元素,则“日期”元素的模板不会匹配。
将此转换应用于以下XML文档:
<Dates> <Date> <VALUE1></VALUE1> <VALUE2> </VALUE2> <VALUE3></VALUE3> <VALUE4></VALUE4> <VALUE5>3333</VALUE5> </Date> <Date> <VALUE1>AAAA</VALUE1> <VALUE2>1</VALUE2> <VALUE3>JJJJ</VALUE3> <VALUE4>1</VALUE4> <VALUE5>12345</VALUE5> </Date> </Dates>
产生了正确的结果:
<Date> <VALUE1>AAAA</VALUE1> <VALUE2>1</VALUE2> <VALUE3>JJJJ</VALUE3> <VALUE4>1</VALUE4> <VALUE5>12345</VALUE5> </Date>
答案 2 :(得分:2)
@是多余的 - 它指的是XML属性。
您正在尝试测试元素,所以只需删除@。
另外:
答案 3 :(得分:2)
<xsl:for-each select="Level1/Level2/Level3">
<MyDates>
<xsl:if test="VALUE1!=''">
<value_1>
<xsl:value-of select="VALUE1"/>
</value_1>
</xsl:if>
<xsl:if test="VALUE2!=''">
<value_2>
<xsl:value-of select="VALUE2"/>
</value_2>
</xsl:if>
<xsl:if test="VALUE3!=''">
<value_3>
<xsl:value-of select="VALUE3"/>
</value_3>
</xsl:if>
<xsl:if test="VALUE4!=''">
<value_4>
<xsl:value-of select="VALUE4"/>
</value_4>
</xsl:if>
</MyDates>
答案 4 :(得分:2)
我想你也可以这样做。而不是检查节点。 VALUE1 / text()将检查节点中是否有一些文本。您可能希望确保没有空白区域。此外,您可以查看VALUE1元素是否具有子节点。
<xsl:if test="VALUE1/text()">
</xsl:if>
<xsl:if test="VALUE1/child::node()">
</xsl:if>
答案 5 :(得分:0)
<xsl:template match="Dates">
<table border="1">
<tr bgcolor="#9acd32"><th>NAME</th><th>INVALUE</th></tr>
<xsl:for-each select="Date">
<xsl:if test="(VALUE1 != '') and (VALUE2 != '') and (VALUE3 != '') and (VALUE4 != '') and (VALUE5 != '')" >
<tr><td>VALUE1</td><td><xsl:value-of select="VALUE1"></xsl:value-of></td></tr>
<tr><td>VALUE2</td><td><xsl:value-of select="VALUE2"></xsl:value-of></td></tr>
<tr><td>VALUE3</td><td><xsl:value-of select="VALUE3"></xsl:value-of></td></tr>
<tr><td>VALUE4</td><td><xsl:value-of select="VALUE4"></xsl:value-of></td></tr>
<tr><td>VALUE5</td><td><xsl:value-of select="VALUE5"></xsl:value-of></td></tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>