2016-03-06 83 views
1

我現在面臨一個奇怪的問題(恕我直言)的,總之,是一個節點列表:XSL:排序爲PARAM傳遞給一個模板

作爲參數傳遞到模板的節點列表不能排序。

下面是一個例子。

輸入文件是:

<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> 

但是,如果我運行轉換,只是一個空生成了「根」元素,沒有子節點。

如果我註釋掉標有'*****'的行,生成的根元素確實包含子元素,但未排序(如本例所期望的那樣)。

如果我直接處理元素(而不是在模板中傳遞列表作爲參數處理),那麼我可以使用'sort',並且一切都按預期工作。這裏是「直接」改造:

<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> 

所以我的問題是:爲什麼不是作爲參數傳遞給一個「排序」選項處理的模板傳遞一個列表?從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

我無法重現您的問題。你在使用哪種處理器? –

+0

我使用Ant中內建的一個(我從Ant腳本開始轉換),我不知道它到底是什麼。 你是否在這兩種情況下得到相同的結果? – fml2

+0

@ fml2 - 下面是一個正常工作的例子。 http://xsltransform.net/ncdD7n5嘗試任何可用的處理器;他們排序正確。 (爲了便於閱讀,我添加了'indent =「yes」'。) –

回答

1

我解決了這個問題,明確指定要使用的XSL處理器。在我看來,我使用的JDK(我試過JRE7和JRE8)包含一箇舊版本的XSL處理器,它不能正確處理文件。

我下載了Xalan 2.7.2並在'xslt'ant任務中指定了它的JAR,並立即得到了正確的結果。

我也試過撒克遜9號,也得到了正確的結果。

我很驚訝現代JRE與有缺陷的XSL處理器打包在一起。我認爲我所執行的轉變並不複雜。

相關問題