2017-02-03 4 views
0

В следующих XML-данных несколько элементов имеют разные идентификаторы. Например, элемент «apfel» имеет несколько идентификаторов, а не один и тот же.ХОТИТЕ: xslt взломать, чтобы избавиться от дубликатов на выходе

<lieferungen> 
    <artikel id="3526"> 
     <name>apfel</name> 
     <lieferant>Fa. Krause</lieferant> 
     <preis stueckpreis="true">8.97</preis> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <preis stueckpreis="false">10.45</preis> 
     <lieferant>Fa. Helbig</lieferant> 
    </artikel> 
    <artikel id="3526"> 
     <preis stueckpreis="true">12.67</preis> 
     <lieferant>Fa. Liebig</lieferant> 
     <name>apfel</name> 
    </artikel> 
    <artikel id="7866"> 
     <preis stueckpreis="false">17.67</preis> 
     <name>Kirschen</name> 
     <lieferant>Fa. Krause</lieferant> 
    </artikel> 
    <artikel id="3627"> 
     <name>apfel</name> 
     <lieferant>Fa. Mertes</lieferant> 
     <preis stueckpreis="true">9.54</preis> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <lieferant>Fa. Hoeller</lieferant> 
     <preis stueckpreis="false">16.45</preis> 
    </artikel> 
    <artikel id="7868"> 
     <preis>3.20</preis> 
     <name>Kohl</name> 
     <lieferant>Fa. Hoeller</lieferant> 
    </artikel> 
    <artikel id="7866"> 
     <name>Kirschen</name> 
     <lieferant>Fa. Richard</lieferant> 
     <preis stueckpreis="false">12.45</preis> 
    </artikel> 
    <artikel id="3245"> 
     <preis stueckpreis="false">15.67</preis> 
     <name>Bananen</name> 
     <lieferant>Fa. Hoeller</lieferant> 
    </artikel> 
    <artikel id="6745"> 
     <name>Kohl</name> 
     <lieferant>Fa. Reinhardt</lieferant> 
     <preis stueckpreis="false">3.10</preis> 
    </artikel> 
    <artikel id="7789"> 
     <name>Ananas</name> 
     <preis stueckpreis="true">8.60</preis> 
     <lieferant>Fa. Richard</lieferant> 
    </artikel> 
</lieferungen> 

я хочу подвести итог несоответствия следующим образом:

enter image description here

С этой целью я написал следующий XSLT-код:

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

    <xsl:template match="lieferungen"> 
     <html> 
      <head> 
       <title> 
        <xsl:text>Inkonsistenzen</xsl:text> 
       </title> 
      </head> 
      <body bgcolor="#ffffff"> 
       <h1> 
        <xsl:text>Inkonsistenzen</xsl:text> 
       </h1> 
       <hr/> 
       <p> 
        <xsl:text>Die Datei enthält folgende Inkonsistenzen: 
       </xsl:text> 
       </p> 
        <xsl:apply-templates/> 
       <hr/> 

      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="artikel"> 
     <xsl:variable name="this_name" select="name/text()"/> 
     <xsl:variable name="this_id" select="@id"/> 
     <xsl:variable name="this_prod" select="lieferant/text()"/> 

     <xsl:for-each select="//artikel"> 
      <xsl:if test="name/text() = $this_name"> 
       <xsl:if test="not(@id = $this_id)"> 
        <p> 
         <xsl:text>Inkonsistenz: Name1=</xsl:text> 
         <xsl:value-of select="$this_name"/> 
         <xsl:text>; Lieferant1=</xsl:text> 
         <xsl:value-of select="$this_prod"/> 
         <xsl:text>; ID1=</xsl:text> 
         <u> 
          <b> 
           <xsl:value-of select="$this_id"/> 
          </b> 
         </u> 
         <xsl:text> ; Name2=</xsl:text> 
         <xsl:value-of select="name/text()"/> 
         <xsl:text>; Lieferant2=</xsl:text> 
         <xsl:value-of select="lieferant/text()"/> 
         <xsl:text>; ID2=</xsl:text> 
         <u> 
          <b> 
           <xsl:value-of select="@id"/> 
          </b> 
         </u> 
        </p> 
       </xsl:if> 
      </xsl:if> 
     </xsl:for-each> 

    </xsl:template> 

</xsl:stylesheet> 

Выход этого является следующие:

Inkonsistenzen 


    Die Datei enthält folgende Inkonsistenzen: 
    Inkonsistenz: Name1=apfel; Lieferant1=Fa. Krause; ID1=3526 ; Name2=apfel;  
    Lieferant2=Fa. Mertes; ID2=3627 
    Inkonsistenz: Name1=apfel; Lieferant1=Fa. Liebig; ID1=3526 ; Name2=apfel; 
    Lieferant2=Fa. Mertes; ID2=3627 
    Inkonsistenz: Name1=apfel; Lieferant1=Fa. Mertes; ID1=3627 ; Name2=apfel; 
    Lieferant2=Fa. Krause; ID2=3526 
    Inkonsistenz: Name1=apfel; Lieferant1=Fa. Mertes; ID1=3627 ; Name2=apfel; 
    Lieferant2=Fa. Liebig; ID2=3526 
    Inkonsistenz: Name1=Kohl; Lieferant1=Fa. Hoeller; ID1=7868 ; Name2=Kohl; 
    Lieferant2=Fa. Reinhardt; ID2=6745 
    Inkonsistenz: Name1=Kohl; Lieferant1=Fa. Reinhardt; ID1=6745 ; Name2=Kohl; 
    Lieferant2=Fa. Hoeller; ID2=7868 

Итак, вывод содержит ровно вдвое больше элементов, чем я хотел. Причиной этого является то, что каждый Лиферант (поставщик) появляется как Лиферант 1 (поставщик 1), так и как Лиферант 2 (поставщик 2).

Код ответственный за дублирование является следующим:

  <xsl:for-each select="//artikel"> 
      <xsl:if test="name/text() = $this_name"> 
       <xsl:if test="not(@id = $this_id)"> 
        <p> 
         <xsl:text>Inkonsistenz: Name1=</xsl:text> 
         <xsl:value-of select="$this_name"/> 
         <xsl:text>; Lieferant1=</xsl:text> 
         <xsl:value-of select="$this_prod"/> 
         <xsl:text>; ID1=</xsl:text> 
         <u> 
          <b> 
           <xsl:value-of select="$this_id"/> 
          </b> 
         </u> 
         <xsl:text> ; Name2=</xsl:text> 
         <xsl:value-of select="name/text()"/> 
         <xsl:text>; Lieferant2=</xsl:text> 
         <xsl:value-of select="lieferant/text()"/> 
         <xsl:text>; ID2=</xsl:text> 
         <u> 
          <b> 
           <xsl:value-of select="@id"/> 
          </b> 
         </u> 
        </p> 
       </xsl:if> 
      </xsl:if> 
     </xsl:for-each> 

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

+0

Это кажется * группировка * проблема. Если вы используете XSLT 1.0, прочитайте, как лучше всего его обрабатывать здесь: http://www.jenitennison.com/xslt/grouping/muenchian.html –

ответ

2

Самым простым способом исправить это, чтобы изменить эту строку ...

<xsl:for-each select="//artikel"> 

Для этого ..

<xsl:for-each select="following-sibling::artikel"> 

То есть, а не сравнить против всех artikels, просто сравнить те, которые следуют за ним (потому что предыдущие уже были рассмотрены).

Обратите внимание, что вы можете избежать некоторых вложенности, но с добавлением условий в двух xsl:if к xsl:for-each вместо

<xsl:for-each select="following-sibling::artikel[name = $this_name][not(@id = $this_id)]"> 
+0

Спасибо за решение! – Tommy

Смежные вопросы