Java中xsl:for-each的错误行为

Java中xsl:for-each的错误行为,java,xml,xslt,Java,Xml,Xslt,与使用XMLSpy进行测试相比,在Java程序中应用XSLT时,我看到了不一致的行为。具体地说,在使用Java时,xsl:for-each指令似乎不会遍历整个列表。使用XMLSpy进行测试时,情况并非如此 我的XML文档: <metadata xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <maps> &l

与使用XMLSpy进行测试相比,在Java程序中应用XSLT时,我看到了不一致的行为。具体地说,在使用Java时,
xsl:for-each
指令似乎不会遍历整个列表。使用XMLSpy进行测试时,情况并非如此

我的XML文档:

<metadata xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <maps>
        <geographicCoverages>
            <coverage key="ON">Ontario</coverage>
            <coverage key="MB">Manitoba</coverage>
            <coverage key="SK">Saskatchewan</coverage>
            <coverage key="AB">Alberta</coverage>
            <coverage key="BC">British Columbia</coverage>
            <coverage key="YT">Yukon</coverage>
            <coverage key="NU">Nunavut</coverage>
        </geographicCoverages>
    </maps>
  <entry>
    <string>GEO_COVERAGE</string>
    <list>
      <string>BC</string>
      <string>ON</string>
    </list>
  </entry>
  ...
</metadata>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" version="1.0" indent="yes"/>

<xsl:key name="geoCoverageKey" match="metadata/maps/geographicCoverages/coverage" use="@key" />

<xsl:template match="/metadata">

<xsl:for-each select="entry[string='GEO_COVERAGE']/list">
    <xsl:value-of select="key('geoCoverageKey', string)" separator=", " />
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>
public static void main(String[] args) throws TransformerException {
    String xsltPath = "test_migration.xslt";
    String xmlPath = "test-migration.xml";
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer(new StreamSource(xsltPath));

    StreamResult result = new StreamResult( new StringWriter() );

    transformer.transform(new StreamSource(xmlPath), result );
    System.out.println( result.getWriter().toString() );
}
我的Java测试程序:

<metadata xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <maps>
        <geographicCoverages>
            <coverage key="ON">Ontario</coverage>
            <coverage key="MB">Manitoba</coverage>
            <coverage key="SK">Saskatchewan</coverage>
            <coverage key="AB">Alberta</coverage>
            <coverage key="BC">British Columbia</coverage>
            <coverage key="YT">Yukon</coverage>
            <coverage key="NU">Nunavut</coverage>
        </geographicCoverages>
    </maps>
  <entry>
    <string>GEO_COVERAGE</string>
    <list>
      <string>BC</string>
      <string>ON</string>
    </list>
  </entry>
  ...
</metadata>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" version="1.0" indent="yes"/>

<xsl:key name="geoCoverageKey" match="metadata/maps/geographicCoverages/coverage" use="@key" />

<xsl:template match="/metadata">

<xsl:for-each select="entry[string='GEO_COVERAGE']/list">
    <xsl:value-of select="key('geoCoverageKey', string)" separator=", " />
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>
public static void main(String[] args) throws TransformerException {
    String xsltPath = "test_migration.xslt";
    String xmlPath = "test-migration.xml";
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer(new StreamSource(xsltPath));

    StreamResult result = new StreamResult( new StringWriter() );

    transformer.transform(new StreamSource(xmlPath), result );
    System.out.println( result.getWriter().toString() );
}

然而,当我运行上面的Java测试程序时,我得到的输出只包含一个值;安大略。我不知道为什么会出现这种差异。

JDK中的默认处理器是Xalan。Xalan是XSLT1.0处理器。当XSLT 1.0处理程序获得指定version=“2.0”的样式表时,需要(根据XSLT 1.0处理程序的规则)忽略XSLT 1.0中未定义的属性。“分隔符”属性属于这一类。在XSLT1.0中,xsl:value of输出节点集中的第一个节点,并忽略其余节点


答案是安装Saxon,它用Java提供XSLT2.0处理。

您使用的是什么处理器?Java的可能不是XSLT 2.0,因此您的值中的分隔符选项可能不起作用。您完全正确,不到一天左右,我就找到了相同的解决方案。虽然你的详细解释填补了空白,说明了原因。非常感谢!