java - 使用 Muenchian 分组方法的 XSLT 问题

标签 java xslt muenchian-grouping

我在对文档中的一组节点进行分组并根据一组包含的值获取唯一列表时遇到了一个非常奇怪的问题。

给定以下 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>

我正在尝试生成一个以竖线分隔的字符串,其中包含“Friend”标签中的所有名称。这是我当前使用的样式表:

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

我遇到的问题是输出忽略了最后一个 friend 。结果如下:

Billy Bob Smith|

有趣的是,如果我删除最后一个“Gift”元素,它会产生我正在寻找的输出:

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();
    }
  }
}

欢迎您提供任何帮助。

最佳答案

您使用 Saxon 6.5 测试的转换运行良好,并且产生了想要的结果:

Billy Bob Smith|Mary Jo Smith

这可能是与 java XSLT api 相关的问题。该 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>

关于java - 使用 Muenchian 分组方法的 XSLT 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6363649/

相关文章:

java - Getter 方法返回错误值

java - 从 C 代码调用 Java

xml - XSL 将具有属性的 xml 行转换为无序列表 TreeView

xml - xslt 1.0 使用复合键分组(在不同级别)

java - Android 编程新手,尝试创建导致登录屏幕的登录按钮。当我单击登录按钮时,应用程序显示 "stopped working"

java - 使用 ImageView 打开新 Activity ?

XSLT 命名空间和默认命名空间问题

xml - 对一个 xml 文件进行排序并让另一个文件跟随

java - 大型 XML 的 XML 节点到字符串转换

XSLT/慕尼黑分组 : how to select element with certain sub-element from group?