我面临一个奇怪的问题(恕我直言),简而言之就是:
作为参数传递给模板的节点列表无法排序。
以下是一个例子。
输入文件是:
<root>
<a>BBB</a>
<a>AAA</a>
</root>
转型是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/">
<Root>
<xsl:call-template name="processThis">
<xsl:with-param name="nodeList" select="/*/a"/>
</xsl:call-template>
</Root>
</xsl:template>
<xsl:template name="processThis">
<xsl:param name="nodeList" />
<xsl:for-each select="$nodeList">
<xsl:sort /><!-- ***** This causes the problem -->
<xsl:variable name="thisVal" select="." />
<result value="{$thisVal}" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
预期输出为:
<Root>
<result value="AAA" />
<result value="BBB" />
</Root>
但如果我进行转换,只需要一个空的&#39; Root&#39;生成元素,没有子节点。
如果我注释掉标有&#39; *****&#39;的行,则生成的Root元素确实包含子元素,但未排序(在这种情况下可以预期)。
如果我直接处理元素(而不是在传递列表的模板中作为参数处理),那么我可以使用&#39; sort&#39;,一切都按预期工作。这是&#39;直接&#39;转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/">
<Root>
<xsl:for-each select="/*/a">
<xsl:sort />
<xsl:variable name="thisVal" select="." />
<result value="{$thisVal}" />
</xsl:for-each>
</Root>
</xsl:template>
</xsl:stylesheet>
所以我的问题是:为什么没有一个列表作为参数传递给使用&#39;排序&#39;处理的模板。选项?
2016年3月7日更新:
XmlSpy和一些在线XSL处理器提供预期的(排序的)输出。
我已经尝试使用独立的Java程序,它给了我错误的结果。这是程序:
package my.test;
import java.io.File;
import java.io.StringWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class Transform {
public static void main(String[] args) throws Exception {
String inputFileName = "Q:\\MiscThings\\t\\a.xml";
String xslFileName = "Q:\\MiscThings\\t\\trans.xsl";
Source xmlSource = new StreamSource(new File(inputFileName));
Source xslSource = new StreamSource(new File(xslFileName));
StringWriter stringWriter = new StringWriter();
Result transformationResult = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xslSource);
transformer.transform(xmlSource, transformationResult);
stringWriter.flush();
String xmlResult = stringWriter.toString();
System.out.println(xmlResult);
}
}
答案 0 :(得分:1)
我通过明确指定要使用的XSL处理器解决了这个问题。在我看来,我使用的JDK(我试过JRE7和JRE8)包含一个旧版本的XSL处理器,它不能正确处理文件。
我下载了Xalan 2.7.2并在&#39; xslt&#39;中指定了它的JAR。蚂蚁任务 - 并立即得到正确的结果。
我也尝试过saxon 9,并且得到了正确的结果。
我对现代JRE与有缺陷的XSL处理器打包这一事实感到惊讶。在我看来,我执行的转换并不复杂。