1

我正在使用 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

我该如何解决?任何帮助是极大的赞赏。谢谢。

4

1 回答 1

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 名称空间,就像开车一样,是一个通过一些培训而不是通过反复试验更好地学习的主题。阅读这样的简短文章将帮助您避免很多困惑和痛苦。

于 2012-08-20T14:32:27.660 回答