XSLT - xpath axes uvnitř cyklu

Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #30 kdy: 18. 07. 2021, 16:11:44 »
Pokud platí, že na vstupu jsou řádky správně seřazené, pak bude fungovat např. toto:

Kód: [Vybrat]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <Workbook>
            <xsl:apply-templates select="ResultsSet/ResultSet[1]/Row"/>
        </Workbook>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[1]/Row">
        <xsl:variable name="id" select="Parent"/>
        <Pack>
            <Type>Pallet</Type>
            <ID><xsl:value-of select="$id" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[2]/Row[Parent = $id][1]/preceding-sibling::Row) + 1" /></Sequence>           
        </Pack>
        <xsl:apply-templates select="/ResultsSet/ResultSet[2]/Row[Parent=$id]"/>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[2]/Row">
        <xsl:variable name="current" select="."/>
        <Pack>
            <Type>Box</Type>
            <ID><xsl:value-of select="Child" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[1]/Row[Parent = $current/Parent]/preceding-sibling::Row) + 2" /></Sequence>           
            <Parent><xsl:value-of select="Parent" /></Parent>
        </Pack>
    </xsl:template>   
</xsl:stylesheet>

BoneFlute si může všimnout, že to není imperativní program, takže tam není žádná pojmenovaná funkce (šablona) ani žádný cyklus.


BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #31 kdy: 18. 07. 2021, 16:43:34 »
Pokud platí, že na vstupu jsou řádky správně seřazené, pak bude fungovat např. toto:

Kód: [Vybrat]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <Workbook>
            <xsl:apply-templates select="ResultsSet/ResultSet[1]/Row"/>
        </Workbook>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[1]/Row">
        <xsl:variable name="id" select="Parent"/>
        <Pack>
            <Type>Pallet</Type>
            <ID><xsl:value-of select="$id" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[2]/Row[Parent = $id][1]/preceding-sibling::Row) + 1" /></Sequence>           
        </Pack>
        <xsl:apply-templates select="/ResultsSet/ResultSet[2]/Row[Parent=$id]"/>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[2]/Row">
        <xsl:variable name="current" select="."/>
        <Pack>
            <Type>Box</Type>
            <ID><xsl:value-of select="Child" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[1]/Row[Parent = $current/Parent]/preceding-sibling::Row) + 2" /></Sequence>           
            <Parent><xsl:value-of select="Parent" /></Parent>
        </Pack>
    </xsl:template>   
</xsl:stylesheet>

BoneFlute si může všimnout, že to není imperativní program, takže tam není žádná pojmenovaná funkce (šablona) ani žádný cyklus.

Negeneruje to požadovaný výsledek. Nesedí Parent.

Jestli chceš být užitečný, zkus se pochlubit jak se dělá to "Dá se udělat to, že výstup XSLT transformace proženete další transformací (klidně i v rámci jedné šablony)". To neumím, to mě zajímá.

Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #32 kdy: 18. 07. 2021, 17:49:20 »
Negeneruje to požadovaný výsledek. Nesedí Parent.
Ono se tu těžko hledá, co má být vlastně vstupem a co výstupem, když je to rozcourané po různých komentářích. Místo zbytečných keců jste takovou trivialitu mohl opravit.

Oprava je zde:
Kód: [Vybrat]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <Workbook>
            <xsl:apply-templates select="ResultsSet/ResultSet[1]/Row"/>
        </Workbook>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[1]/Row">
        <xsl:variable name="id" select="Parent"/>
        <Pack>
            <Type>Pallet</Type>
            <ID><xsl:value-of select="$id" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[2]/Row[Parent = $id][1]/preceding-sibling::Row) + 1" /></Sequence>           
        </Pack>
        <xsl:apply-templates select="/ResultsSet/ResultSet[2]/Row[Parent=$id]"/>
    </xsl:template>

    <xsl:template match="/ResultsSet/ResultSet[2]/Row">
        <xsl:variable name="current" select="."/>
        <Pack>
            <Type>Box</Type>
            <ID><xsl:value-of select="Child" /></ID>
            <Sequence><xsl:value-of select="count(preceding-sibling::Row) + count(/ResultsSet/ResultSet[1]/Row[Parent = $current/Parent]/preceding-sibling::Row) + 2" /></Sequence>           
            <Parent><xsl:value-of select="count(preceding-sibling::Row[Parent != $current/Parent]) + count(/ResultsSet/ResultSet[1]/Row[Parent = $current/Parent]/preceding-sibling::Row) + 1" /></Parent>
        </Pack>
    </xsl:template>
   
</xsl:stylesheet>

Jestli chceš být užitečný, zkus se pochlubit jak se dělá to "Dá se udělat to, že výstup XSLT transformace proženete další transformací (klidně i v rámci jedné šablony)". To neumím, to mě zajímá.
Považuji za užitečné to, že jsem tazateli poradil, jak vyřešit jeho problém.

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #33 kdy: 18. 07. 2021, 19:30:28 »
Negeneruje to požadovaný výsledek. Nesedí Parent.
Místo zbytečných keců

Omlouvám se. Napsat to kratšeji mi už přišlo hulvátské.


...
Co říkáš, na toto řešení? Toto ti funguje?

ZAJDAN

  • *****
  • 2 089
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #34 kdy: 18. 07. 2021, 23:31:44 »
....
Zítra to s čistou hlavou znovu zkusím.

....
Docela se stydím přiznat, že tento standardní přístup jsem při používání XSLT nevyužíval a všude používám for-each.
Zkouším tu Vaši variantu, ale neiteruje mi to. Vytvoří to jen jednu paletu a jeden box.
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 - xpath axes uvnitř cyklu
« Odpověď #35 kdy: 19. 07. 2021, 10:58:15 »
Zkouším tu Vaši variantu, ale neiteruje mi to. Vytvoří to jen jednu paletu a jeden box.
Já jsem to zkoušel na datech z komentáře č. 4 a fungovalo to. Zkoušel jsem to v Oxygenu, který interně používá Saxon. Buď ta vstupní data vypadají jinak, nebo to, na čem to spouštíte, není XSLT procesor, ale jenom nějaká nepovedená napodobenina. Protože to, že xsl:apply-templates se aplikuje na všechny uzly odpovídající selektoru, je úplně tou nejzákladnější vlastností XSLT.

Kit

  • *****
  • 716
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #36 kdy: 19. 07. 2021, 11:21:40 »
Zkouším tu Vaši variantu, ale neiteruje mi to. Vytvoří to jen jednu paletu a jeden box.
Já jsem to zkoušel na datech z komentáře č. 4 a fungovalo to. Zkoušel jsem to v Oxygenu, který interně používá Saxon. Buď ta vstupní data vypadají jinak, nebo to, na čem to spouštíte, není XSLT procesor, ale jenom nějaká nepovedená napodobenina. Protože to, že xsl:apply-templates se aplikuje na všechny uzly odpovídající selektoru, je úplně tou nejzákladnější vlastností XSLT.

Zkusil jsem to v xsltproc a také to jede bez potíží. Do elementu Sequence postupně vygeneruje hodnoty 1-8.

ZAJDAN

  • *****
  • 2 089
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #37 kdy: 20. 07. 2021, 10:37:25 »
Pánové moc díky za Vaše rady a nápady, které jste mi poskytli.
On ten Integrační framework od SAPu je taková parní lokomotiva :) a ne všechno tam funguje standardně.
Každopádně si nejsem jist, zda mohu 'apply-templates' použít uvnitř volané template.
Kód: [Vybrat]
<xsl:template match="/">
            <vpf:Msg>
                <xsl:copy-of select="/vpf:Msg/@*"></xsl:copy-of>
                <xsl:copy-of select="/vpf:Msg/vpf:Header"></xsl:copy-of>
                <vpf:Body>
                    <xsl:copy-of select="/vpf:Msg/vpf:Body/*"></xsl:copy-of>
                    <vpf:Payload Role="X" id="{$atom}">
                        <xsl:call-template name="transform"></xsl:call-template>
                    </vpf:Payload>
                </vpf:Body>
            </vpf:Msg>
</xsl:template>

<xsl:template name="transform">
....
....
.....
<xsl:template match="/">
   <Pack>
   <xsl:apply-templates select="/vpf:Msg/vpf:Body/vpf:Payload[@id='CallSQL']/jdbc:ResultSets/jdbc:ResultSet[3]/jdbc:Row"></xsl:apply-templates>   
   </Pack>
</xsl:template>

</xsl:template>

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.

Kit

  • *****
  • 716
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #38 kdy: 20. 07. 2021, 10:58:05 »
Každopádně si nejsem jist, zda mohu 'apply-templates' použít uvnitř volané template.

Ano, je možné ho použít uvnitř a funguje i rekurzívně.

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #39 kdy: 20. 07. 2021, 11:26:35 »
Pánové moc díky za Vaše rady a nápady, které jste mi poskytli.
On ten Integrační framework od SAPu je taková parní lokomotiva :) a ne všechno tam funguje standardně.
Každopádně si nejsem jist, zda mohu 'apply-templates' použít uvnitř volané template.
jj, můžeš, ale v tvém případě platí - to prostě zkus, je-li ten SAP tak nestandardní.

Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #40 kdy: 20. 07. 2021, 16:15:18 »
Pánové moc díky za Vaše rady a nápady, které jste mi poskytli.
On ten Integrační framework od SAPu je taková parní lokomotiva :) a ne všechno tam funguje standardně.
Každopádně si nejsem jist, zda mohu 'apply-templates' použít uvnitř volané template.
Kód: [Vybrat]
<xsl:template name="transform">
....
....
.....
<xsl:template match="/">
   <Pack>
   <xsl:apply-templates select="/vpf:Msg/vpf:Body/vpf:Payload[@id='CallSQL']/jdbc:ResultSets/jdbc:ResultSet[3]/jdbc:Row"></xsl:apply-templates>   
   </Pack>
</xsl:template>

</xsl:template>
Utčitě není možné v XSLT mít xsl:template uvnitř jiného xsl:template. Ten váš příklad by měl vypadat např. takto:

Kód: [Vybrat]
<xsl:template match="/">
            <vpf:Msg>
                <xsl:copy-of select="/vpf:Msg/@*"></xsl:copy-of>
                <xsl:copy-of select="/vpf:Msg/vpf:Header"></xsl:copy-of>
                <vpf:Body>
                    <xsl:copy-of select="/vpf:Msg/vpf:Body/*"></xsl:copy-of>
                    <vpf:Payload Role="X" id="{$atom}">
                        <xsl:apply-templates select="/vpf:Msg/vpf:Body/vpf:Payload[@id='CallSQL']" />
                    </vpf:Payload>
                </vpf:Body>
            </vpf:Msg>
</xsl:template>

<xsl:template match="/vpf:Msg/vpf:Body/vpf:Payload[@id='CallSQL']">
   <Pack>
   <xsl:apply-templates select="jdbc:ResultSets/jdbc:ResultSet[3]/jdbc:Row" />
   </Pack>
</xsl:template>


ZAJDAN

  • *****
  • 2 089
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #41 kdy: 21. 07. 2021, 09:54:45 »
@BoneFlute
tak verzi co jsi mi poslal už jsem zprovoznil
@Filip Jirsák
šablony určitě také zkusím, snad se k tomu dnes dostanu

všem díky!
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.

BoneFlute

  • *****
  • 2 000
    • Zobrazit profil
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #42 kdy: 22. 07. 2021, 17:31:30 »
@BoneFlute
tak verzi co jsi mi poslal už jsem zprovoznil
@Filip Jirsák
šablony určitě také zkusím, snad se k tomu dnes dostanu

všem díky!

Rádo se stalo. V čem byl problém?

ZAJDAN

  • *****
  • 2 089
    • Zobrazit profil
    • E-mail
Re:XSLT - xpath axes uvnitř cyklu
« Odpověď #43 kdy: 23. 07. 2021, 12:42:51 »
Rádo se stalo. V čem byl problém?
u jednoho elementu mi chyběl namespace
jdbc: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.