XSLT 1.0 - porovnávání v cyklu

ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
XSLT 1.0 - porovnávání v cyklu
« kdy: 13. 10. 2021, 21:13:46 »
Ahoj...
mám xml:
Kód: [Vybrat]
<Main>
 <Payload id="A1">
  <Data>
    <row>
      <Qty>10</Qty>
      <Date>10-11-2021</Date>
    </row>
  </Data>
 </Payload>

 <Payload id="A2">
  <Data>
    <row>
      <Qty>10</Qty>
      <Date>10-11-2021</Date>
    </row>   
    <row>
      <Qty>20</Qty>
      <Date>10-11-2021</Date>
    </row>   
  </Data>
 </Payload>
</Main>
a xslt:
Kód: [Vybrat]
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="/">
        <xsl:for-each select="/Main/Payload[@id='A2']/Data/row">
        <Unique>
           <Qty><xsl:value-of select="Qty"/></Qty>
           <Qty><xsl:value-of select="Date"/></Qty>
        </Unique>
        </xsl:for-each>
    </xsl:template>
</xsl:transform>

Potřebuji projít všechny elementy <row> v Payload[@id='A2'] a porovnat hodnoty v jejich vnitřních elementech <Qty>,<Date> proti   Payload[@id='A1'] .

Cílem je identifikovat stejné hodnoty v <Qty> a <Date> obou Payloadů a vypsat pouze jedinečné.

Díky za radu
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.


Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #1 kdy: 13. 10. 2021, 21:31:07 »
To se nedělá pomocí cyklu ale pomocí podmínky […]. To vaše zadání není úplně podrobné, ale ten XPath výraz může být třeba nějak takto:

Kód: [Vybrat]
/Main/Payload[@id='A2']/Data/row/Qty[. != /Main/Payload[@id='A1']/Data/row/Qty]

ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #2 kdy: 13. 10. 2021, 21:52:05 »
To se nedělá pomocí cyklu ale pomocí podmínky […]. To vaše zadání není úplně podrobné, ale ten XPath výraz může být třeba nějak takto:

Kód: [Vybrat]
/Main/Payload[@id='A2']/Data/row/Qty[. != /Main/Payload[@id='A1']/Data/row/Qty]

Kód: [Vybrat]
<?xml version="1.0" encoding="UTF-8"?>
<Main>
 <Payload id="A1">
  <Data>
    <row>
      <Qty>10</Qty>
      <Date>10-11-2021</Date>
    </row>
        <row>
      <Qty>20</Qty>
      <Date>10-11-2021</Date>
    </row>
  </Data>
 </Payload>

 <Payload id="A2">
  <Data>
    <row>
      <Qty>10</Qty>
      <Date>10-11-2021</Date>
    </row>   
    <row>
      <Qty>20</Qty>
      <Date>10-11-2021</Date>
    </row>
        <row>
      <Qty>30</Qty>
      <Date>10-12-2021</Date>
    </row>
  </Data>
 </Payload>
</Main>

Kód: [Vybrat]
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="/">
        <xsl:for-each select="/Main/Payload[@id='A2']/Data/row">
          <xsl:if test="Qty[. != /Main/Payload[@id='A1']/Data/row/Qty]">
              <Unique>
                 <Qty><xsl:value-of select="Qty"/></Qty>
                 <Date><xsl:value-of select="Date"/></Date>
              </Unique>
        </xsl:if>
      </xsl:for-each>
    </xsl:template>
</xsl:transform>
Dle uvedeného příkladu bych potřeboval vypsat jedinečný záznam, cože je Qty 30 Date 10.12.2021, což mi nejde.
http://xsltransform.net/bdxZ9d/4
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.

Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #3 kdy: 13. 10. 2021, 22:04:33 »
Takhle, vždycky zapomenu, jak se chovají negace spolu se sekvencemi:
Kód: [Vybrat]
/Main/Payload[@id='A2']/Data/row/Qty[not(. = /Main/Payload[@id='A1']/Data/row/Qty)]

ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #4 kdy: 13. 10. 2021, 22:38:52 »
Takhle, vždycky zapomenu, jak se chovají negace spolu se sekvencemi:
Kód: [Vybrat]
/Main/Payload[@id='A2']/Data/row/Qty[not(. = /Main/Payload[@id='A1']/Data/row/Qty)]
Díky,už je to velice blízko. Jak ale kontrolovat navíc i hodnotu v elementu Date sousedící v aktuálně kontrolovaném Qty Payloadu 1?
http://xsltransform.net/bdxZ9d/6
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.


ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #5 kdy: 13. 10. 2021, 23:19:23 »
Napadlo mě ty elementy <Qty> a <Date> v jedné transformaci spojit, takže v dalším Payloadu bych měl výstup <QtyDate>10_10-11-2021</QtyDate> a teprve v další transformaci porovnávat tento element.
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.

Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #6 kdy: 14. 10. 2021, 15:38:04 »
Má to být tak, že za duplicitu se považuje, když je stejné Qty a Date, nebo je duplicita, když je stejná alespoň jedna ze dvou hodnot?

ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #7 kdy: 14. 10. 2021, 17:44:35 »
Má to být tak, že za duplicitu se považuje, když je stejné Qty a Date, nebo je duplicita, když je stejná alespoň jedna ze dvou hodnot?
Dobrý den,
duplicita je zde míněna pro oba elementy<Qty><Date> ,ale pouze v rámci jednoho <Row>
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.

Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #8 kdy: 15. 10. 2021, 20:15:25 »
To už konečně nastal čas pro váš oblíbený <xsl:if>. Nenapadá mne, jak ten test udělat bez toho uložení aktuálního řádku do proměnné.

Kód: [Vybrat]
    <xsl:template match="/Main/Payload[@id = 'A2']/Data/row">
        <xsl:variable name="row" select="."/>
        <xsl:if test="count(/Main/Payload[@id = 'A1']/Data/row[Qty = $row/Qty and Date = $row/Date]) = 0">
            <Unique>
                <xsl:copy-of select="$row/Qty"/>
                <xsl:copy-of select="$row/Date"/>
            </Unique>
        </xsl:if>
    </xsl:template>

ZAJDAN

  • *****
  • 2 047
    • Zobrazit profil
    • E-mail
Re:XSLT 1.0 - porovnávání v cyklu
« Odpověď #9 kdy: 16. 10. 2021, 08:44:27 »
Pane Jirsák děkuji!
Funguje to perfektně a díky Vám se člověk opět něco naučil.
Vesele, vesele do továrny dělník běží...vesele, vesele do továrny jde. Vesele se usmívá když mu soustruh zazpívá...vesele, vesele do továrny jde. Vesele si poskočí když se soustruh roztočí ...vesele, vesele do továrny jde.