XSL for-each循环不起作用

时间:2012-08-20 14:24:07

标签: xslt

我正在使用Java将XML文档转换为文本:

Transformer transformer = tFactory.newTransformer(stylesource);
transformer.transform(source, result);

除非XML文档中有冒号,否则这似乎有效。我试过这个例子: XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<test:TEST >
  <one.two:three id="my id" name="my name" description="my description" >
  </one.two:three>
  <one.two:three id="some id" name="some name" description="some description" />
</test:TEST>

XSL文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xmi="http://www.omg.org/XMI" 
xmlns:one.two="http://www.one.two/one.two:three" >
<xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="myVariable">one.two:three</xsl:variable>
<xsl:template match="/">
 <xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[substring(name(),1,9)='test:TEST']" >
 <xsl:for-each select="./$myVariable">
inFirstLoop
 </xsl:for-each>
 <xsl:for-each select="./one.two:three">
inSecondLoop
 </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我得到的转变结果是一行:

inFirstLoop

我期待4行输出

inFirstLoop
inFirstLoop
inSecondLoop
inSecondLoop

我该如何解决这个问题?任何帮助是极大的赞赏。感谢。

1 个答案:

答案 0 :(得分:2)

这里有很多错误。我很惊讶您的转换设法完全运行,而不是在解析错误和其他错误上失败。

一个大问题是您的输入XML使用名称空间前缀(这就是冒号的用途)而不会声明它们。像

这样的声明
 xmlns:one.two="http://www.one.two/one.two:three"

需要在源XML以及XSL中。否则,您的源XML格式不正确(根据命名空间规则)。

第二个问题是XPath表达式

./$myVariable

应该抛出错误。我想你想要的是

*[name() = $myVariable]

我要做的第三个改变不是XSLT中的错误,而只是一种糟糕的做事方式......如果你想匹配<test:TEST>,你应该使用命名空间工具来引用命名空间。因此,而不是

<xsl:template match="*[substring(name(),1,9)='test:TEST']" >

使用

<xsl:template match="test:TEST">

更清洁。然后,您需要在样式表的最外层元素上放置名称空间声明,就像您在输入XML文档中必须做的那样:

xmlns:test="...test..."

XML命名空间,例如驾驶汽车,是一个通过一点点培训而不是通过反复试验来学习的主题。 Reading a brief article like this将帮助您避免在路上造成很多混乱和痛苦。