Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: ZAJDAN 13. 10. 2021, 21:13:46

Název: XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: Filip Jirsák 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]
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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 (http://xsltransform.net/bdxZ9d/4)
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: Filip Jirsák 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)]
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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 (http://xsltransform.net/bdxZ9d/6)
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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.
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: Filip Jirsák 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?
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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>
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: Filip Jirsák 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>
Název: Re:XSLT 1.0 - porovnávání v cyklu
Přispěvatel: ZAJDAN 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.