【问题标题】:XSLT Problem Using Muenchian Method of Grouping使用 Muenchian 分组方法的 XSLT 问题
【发布时间】:2011-06-15 20:04:50
【问题描述】:

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

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

有趣的是,如果我删除最后一个“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();
    }
  }
}

欢迎您提供任何帮助。

【问题讨论】:

    标签: java xslt muenchian-grouping


    【解决方案1】:

    您使用 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>
    

    【讨论】:

    • 嗯,这就解释了。谢谢。
    • 我没试过。我需要一个快速修复来推出一些东西,所以我使用了:.//Friend 而不是 Gift/Friend。我根据 XML 知道这将是可靠的。
    猜你喜欢
    • 1970-01-01
    • 2015-07-30
    • 2022-11-11
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 2014-03-19
    相关资源
    最近更新 更多