Удаление дублирующих элементов и сбор всех подузлов вместе с xslt - PullRequest
1 голос
/ 10 марта 2012

Я новичок в xslt и у меня неловкая проблема, которую я потратил много часов, но не смог прийти к выводу.Заранее благодарен за любую помощь.

У меня есть XML-документ, подобный этому:

<root>

<ELEMENT id="1" >

<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
</CHILD>

<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>

</ELEMENT>


<ELEMENT id="2" >

<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>


</ELEMENT>

<ELEMENT id="1" >

<CHILD name="aaa">
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>


</ELEMENT>

</root>

Я пытаюсь собрать слова «СОТРУДНИКИ», имеющие одинаковый идентификатор «ЭЛЕМЕНТ» и «ДЕТЯМ»"Назовите вместе и удалите дубликаты" ЭЛЕМЕНТОВ "и" ДЕТЕЙ ".

Я имею в виду, что мне нужен только один, имеющий только одного, но со всеми сотрудниками, принадлежащими к id = 1 name = aaa.Результирующий файл должен выглядеть следующим образом:

<root>
<ELEMENT id="1" >

<CHILD name="aaa">
<EMPLOYEE>Mark</EMPLOYEE>
<EMPLOYEE>John</EMPLOYEE>
<EMPLOYEE>Tim</EMPLOYEE>
</CHILD>

<CHILD name="bbb">
<EMPLOYEE>Tom</EMPLOYEE>
</CHILD>

</ELEMENT>


<ELEMENT id="2" >

<CHILD name="aaa">
<EMPLOYEE>leo</EMPLOYEE>
<EMPLOYEE>Jason</EMPLOYEE>
</CHILD>


</ELEMENT>
</root>

Каким должен быть мой код xslt?Нужно ли выполнять итерации для каждого цикла или мне следует применять рекурсивные шаблоны?

Много tnx


Большое спасибо за ваш полезный ответ.Это далеко за пределы того, что я мог бы достичь.Однако код удаляет некоторые из узлов CHILD, которые он не должен удалять.

Я пытался использовать более сложный xml:

<ROOT>
  <ELEMENT id="1" >
    <CHILD name="aaa">
      <EMPLOYEE>
        asdf
      </EMPLOYEE>
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
    <CHILD name="bbb">
      <EMPLOYEE>
       adsf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="1" >
    <CHILD name="aaa">
          <EMPLOYEE>
       asdf
      </EMPLOYEE>
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
    <CHILD name="ccc">
          <EMPLOYEE>
        asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="2" >
    <CHILD name="ddd">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
    <CHILD name="eee">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="3" >
    <CHILD name="xxx">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
    <CHILD name="yyy">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="4" >
    <CHILD name="ddd">
      <EMPLOYEE>
        asdf
      </EMPLOYEE>

    </CHILD>
    <CHILD name="aaa">
      <EMPLOYEE>
       adsf
      </EMPLOYEE>

    </CHILD>
  </ELEMENT>
  <ELEMENT id="3" >
    <CHILD name="xxx">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
    <CHILD name="aaa">
      <EMPLOYEE>
       asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="1" >
    <CHILD name="aaa">
      <EMPLOYEE>
    asdf
      </EMPLOYEE>

   </CHILD>
    <CHILD name="bbb">
      <EMPLOYEE>
        asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>
  <ELEMENT id="2" >
    <CHILD name="ddd">
      <EMPLOYEE>
        asdf
      </EMPLOYEE>
      <EMPLOYEE>
       asdf
      </EMPLOYEE>

    </CHILD>
    <CHILD name="aaa">
      <EMPLOYEE>
     asdf
      </EMPLOYEE>
    </CHILD>
  </ELEMENT>

</ROOT>

1 Ответ

1 голос
/ 10 марта 2012

Это преобразование :

<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="kElemById" match="ELEMENT" use="@id"/>
     <xsl:key name="kChildByNameAndParentId"
      match="CHILD" use="concat(../@id, '+', @name)"/>
     <xsl:key name="kEmplByAnc" match="EMPLOYEE"
      use="concat(../../@id, '+', ../@name)"/>

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

     <xsl:template match=
      "ELEMENT
         [generate-id()
         =
          generate-id(key('kElemById', @id)[1])
         ]
      ">
       <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <xsl:apply-templates select=
         "../ELEMENT/CHILD
           [generate-id()
           =
            generate-id(key('kChildByNameAndParentId',
                            concat(current()/@id,
                                  '+',
                                  @name
                                  )
                            )[1]
                        )
           ]
         "/>
       </xsl:copy>
     </xsl:template>

     <xsl:template match="CHILD">
       <xsl:copy>
         <xsl:apply-templates select=
         "@*
         |
          key('kEmplByAnc', concat(../@id, '+', @name))"/>
       </xsl:copy>
     </xsl:template>

     <xsl:template match="ELEMENT"/>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<root>
    <ELEMENT id="1" >
        <CHILD name="aaa">
            <EMPLOYEE>Mark</EMPLOYEE>
            <EMPLOYEE>John</EMPLOYEE>
        </CHILD>
        <CHILD name="bbb">
            <EMPLOYEE>Tom</EMPLOYEE>
        </CHILD>
    </ELEMENT>
    <ELEMENT id="2" >
        <CHILD name="aaa">
            <EMPLOYEE>leo</EMPLOYEE>
            <EMPLOYEE>Jason</EMPLOYEE>
        </CHILD>
    </ELEMENT>
    <ELEMENT id="1" >
        <CHILD name="aaa">
            <EMPLOYEE>Tim</EMPLOYEE>
        </CHILD>
    </ELEMENT>
</root>

создает искомое, правильный результат :

<root>
   <ELEMENT id="1">
      <CHILD name="aaa">
         <EMPLOYEE>Mark</EMPLOYEE>
         <EMPLOYEE>John</EMPLOYEE>
         <EMPLOYEE>Tim</EMPLOYEE>
      </CHILD>
      <CHILD name="bbb">
         <EMPLOYEE>Tom</EMPLOYEE>
      </CHILD>
   </ELEMENT>
   <ELEMENT id="2">
      <CHILD name="aaa">
         <EMPLOYEE>leo</EMPLOYEE>
         <EMPLOYEE>Jason</EMPLOYEE>
      </CHILD>
   </ELEMENT>
</root>

Пояснение : правильное использование мюнхенского метода для группировки и клавиши .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...