如果一个数字重复,只显示一次

时间:2011-07-29 16:40:11

标签: xslt repeat

嗨,如果我有以下XML输入文件

<data>
<group id= "1">
<phrase>Doc1</phrase>
<document refid ="3"/>
<document refid ="5"/>
<document refid= "1"/>
</group>
<group id= "2">
 <phrase>Doc2</phrase>
<document refid ="2"/>
<document refid ="3"/>
<document refid= "6"/>
</group>
  <group id= "3">
 <phrase>Doc3</phrase>
<document refid ="2"/>
<document refid ="3"/>
<document refid= "4"/>
</group>
</data>

是否可以使用输出检查每个组以查看文档“refid”编号是否未显示在以前的组中?例如,我希望我的输出为

<data>
 <group id= "1">
 <phrase>Doc1</phrase>
<document refid ="3"/>
<document refid ="5"/>
<document refid= "1"/>
</group>
<group id= "2">
 <phrase>Doc2</phrase>
<document refid ="2"/>
<document refid= "6"/>
</group>
  <group id= "3">
 <phrase>Doc3</phrase>
<document refid= "4"/>
</group>
</data>

我正在尝试在XSLT 1.0中执行此操作。 我希望这能清楚地解释这个问题。我将衷心感谢您的帮助。 谢谢

2 个答案:

答案 0 :(得分:1)

这似乎可以解决问题:

<强> $ cat style.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <!--
    This templates matches the document elements with a @refid that has already been used
    in on of the previous groups. They are simply ignored.
    -->
    <xsl:template match="document[../preceding-sibling::group/document/@refid = current()/@refid]" />


    <!--
    Everything else gets copied to the output.
    -->
    <xsl:template match="@*|*|text()">
        <xsl:copy>
            <xsl:apply-templates select="@*|*|text()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

<强> $ xsltproc style.xsl input.xml

<?xml version="1.0"?>
<data>
    <group id="1">
        <document refid="3"/>
        <document refid="5"/>
        <document refid="1"/>
    </group>
    <group id="2">
        <document refid="2"/>

        <document refid="6"/>
    </group>
    <group id="3">


        <document refid="4"/>
    </group>
</data>

修改:将其合并到您的样式表中,尝试将第49行的for-each更改为:

<xsl:for-each select="document[not(../preceding-sibling::group/document/@refid = current()/@refid)]">

答案 1 :(得分:1)

这是一个有效而简短的解决方案,使用密钥(Muenchian grouping

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:key name="kDocById" match="document" use="@refid"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="group">
        <xsl:copy>
            <xsl:apply-templates select=
            "@*
            |
             node()[not(self::document)]
            |
             document
                  [generate-id()
                  =
                  generate-id(key('kDocById', @refid)[1])
                  ]"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档(反映OP在评论中进行的最新细化):

<data>
    <group id= "1">
        <phrase>Doc1</phrase>
        <document refid ="3"/>
        <document refid ="5"/>
        <document refid= "1"/>
    </group>
    <group id= "2">
        <phrase>Doc2</phrase>
        <document refid ="2"/>
        <document refid ="3"/>
        <document refid= "6"/>
    </group>
    <group id= "3">
        <phrase>Doc3</phrase>
        <document refid ="2"/>
        <document refid ="3"/>
        <document refid= "4"/>
    </group>
</data>

产生了想要的正确结果

<data>
   <group id="1">
      <phrase>Doc1</phrase>
      <document refid="3"/>
      <document refid="5"/>
      <document refid="1"/>
   </group>
   <group id="2">
      <phrase>Doc2</phrase>
      <document refid="2"/>
      <document refid="6"/>
   </group>
   <group id="3">
      <phrase>Doc3</phrase>
      <document refid="4"/>
   </group>
</data>