2011-06-15 84 views
1

我在分組文檔中的一組節點並基於一組包含的值獲取唯一列表時遇到了一個非常奇怪的問題。使用Muenchian分組方法的XSLT問題

給出下面的XML:

<Person> 
    <FirstName>John</FirstName> 
    <MiddleName>Q</MiddleName> 
    <LastName>Person</LastName> 
    <Gift> 
     <Thing>Moon</Thing> 
     <Friend> 
      <FirstName>Billy</FirstName> 
      <MiddleName>Bob</MiddleName> 
      <LastName>Smith</LastName> 
     </Friend> 
     <Friend> 
      <FirstName>Mary</FirstName> 
      <MiddleName>Jo</MiddleName> 
      <LastName>Smith</LastName> 
     </Friend> 
    </Gift> 
    <Gift> 
     <Thing>Pencil</Thing> 
    </Gift> 
</Person> 

我想產生一個管道分隔字符串中的所有「好友」標籤的名稱。這裏是我正在使用的當前樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:key name="Friends" match="Friend" use="concat(FirstName, MiddleName, LastName)"/> 

    <xsl:template match="/Person"> 
    <xsl:for-each select="Gift/Friend[count(. | key('Friends', concat(FirstName, MiddleName, LastName))[1]) = 1]"> 
     <xsl:apply-templates select="."/> 
     <xsl:if test="position()!=last()"> 
     <xsl:text>|</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="Friend"> 
    <xsl:variable name="name"> 
     <xsl:value-of select="FirstName"/><xsl:text> </xsl:text> 
     <xsl:value-of select="MiddleName"/><xsl:text> </xsl:text> 
     <xsl:value-of select="LastName"/><xsl:text> </xsl:text> 
    </xsl:variable> 
    <xsl:value-of select="normalize-space($name)"/> 
    </xsl:template> 

</xsl:stylesheet> 

我遇到的問題是輸出省略了最後一個朋友。下面是結果:

Billy Bob Smith| 

有趣的是,如果我刪除最後一個「禮物」的元素,它產生我在尋找的輸出:

Billy Bob Smith|Mary Jo Smith 

以供參考,在這裏是Java用於執行轉換的代碼:

package testing; 

import java.io.*; 
import javax.xml.transform.*; 
import javax.xml.transform.stream.*; 

public class test 
{ 
    public static void main(String[] args) 
    { 
    try 
    {  
     StreamSource xsl = new StreamSource("xslt/person.xslt"); 
     StreamSource xml = new StreamSource("xslt/person.xml"); 
     Transformer txfm = TransformerFactory.newInstance().newTransformer(xsl); 
     if (txfm != null) 
     { 
     ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
     txfm.transform(xml, new StreamResult(bytes)); 
     System.out.println(bytes.toString()); 
     }  

    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    } 
} 

您可以提供的任何幫助都將受到歡迎。

回答

0

你的變換與撒克遜6.5工作完全測試,它產生的通緝的結果:

Billy Bob Smith|Mary Jo Smith 

這可能是相關的Java API XSLT的問題。可能API不完全支持XSLT 1.0功能,例如xsl:key。您可以進行進一步測試,並嘗試不使用密鑰。

<xsl:template match="/Person"> 
     <xsl:for-each select="Gift/Friend[not(
      concat(FirstName,MiddleName,LastName) 
      = 
      preceding::Friend[concat(FirstName, MiddleName, LastName)] 
      )]"> 
     <xsl:apply-templates select="."/> 
     <xsl:if test="position()!=last()"> 
     <xsl:text>|</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 
+0

好,解釋它:

例如,該模板不使用任何鍵執行相同的任務。謝謝。 – pconrey 2011-06-15 20:52:31

+0

沒有鑰匙工作的版本? – 2011-06-15 20:55:00

+0

我還沒試過。我需要一個快速解決方案來推出一些東西,所以我用://朋友而不是禮物/朋友。我知道基於XML,這將是可靠的。 – pconrey 2011-06-17 16:32:27