我正在使用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
我该如何解决这个问题?任何帮助是极大的赞赏。感谢。
答案 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将帮助您避免在路上造成很多混乱和痛苦。