xslt s offsetem rubrika: Programování: Jiné

9 Taco
položil/-a 6.8.2016

Zdravím.

Mějme takovýto xml zdroj:

  <root>
    <row>
      <item>jedna</item>
      <item>dva</item>
      <item>tři</item>
      <item>čtyři</item>
    </row>
    <row>
      <item index="2">two</item>
      <item>three</item>
      <item>four</item>
    </row>
    <row>
      <item>une</item>
      <item index="3">trois</item>
      <item>quatre</item>
    </row>
  </root>

A chtěl bych nad tím udělat xsl transformaci, ale moc mi to nejde.

Cíl je, vytvořit pro každou řádku row čtyři buňky. Vzhledem k tomu, že elementy item mají posouvací index (viz index=3), tak se mi s tím dělá poněkud blbě.

Zatím jsem se dostal do fáze, kdy to zkouším transformovat rekursivně, první item vygeneruje sebe, a svého dalšího následníka.

Zkoušel jsem udělat šablonu, která mi vrátí hodnotu buňky a offset, ale tam jsem se ztratil, jak to v tom for-each použít.

Díky za radu.

Edit:

Očekávaný výstup:

  <root>
    <row>
      <a>jedna</a>
      <b>dva</b>
      <c>tři</c>
      <d>čtyři</d>
    </row>
    <row>
      <a/>
      <b>two</b>
      <c>three</c>
      <d>four</d>
    </row>
    <row>
      <a>une</a>
      <b/>
      <c>trois</c>
      <d>quatre</d>
    </row>
  </root>
odkaz
3 Fos4
odpověděl/-a 8.8.2016

Na rychlo složeno, samozřejmě lze vylepšit, ale mohlo by fungovat (problem je ten for na 4bunky :( ):

<?xml version="1.0" encoding="utd-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<xsl:output method="xml" encoding="utf-8"
/>
  <xsl:template match="/root">
    <xsl:for-each select="row">
      <row>
        <a>
          <xsl:call-template name="cell">
            <xsl:with-param name="index" select="1" />
          </xsl:call-template>
        </a>
        <b>
          <xsl:call-template name="cell">
            <xsl:with-param name="index" select="2" />
          </xsl:call-template>
        </b>
        <c>
          <xsl:call-template name="cell">
            <xsl:with-param name="index" select="3" />
          </xsl:call-template>
        </c>
        <d>
          <xsl:call-template name="cell">
            <xsl:with-param name="index" select="4" />
          </xsl:call-template>
        </d>
      </row>
    </xsl:for-each>
  </xsl:template>
 
 
  <xsl:template name="cell">
    <xsl:param name="index" />
 
    <xsl:choose>
      <xsl:when test="item[@index = $index]">
        <xsl:value-of select="item[@index = $index]" />
      </xsl:when>
 
      <xsl:otherwise>
        <xsl:value-of select="item[position() = $index]" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
 
</xsl:stylesheet>

Komentáře

  • Fos4 : Po odeslání jsem si všiml, že to je špatně.. nefunguje pokud @index je stejný jako position(). V tom případě bych udělal dvě transformace, kdy první mně přiřadí vždy attribut @index (nebo jinak předpřipraví) a potom druhou to už jednoduše vypíšu.. 8.8.2016
  • Kit : Bylo by to možná hezké, kdyby to fungovalo. Zkoušel jsem to podobně. V tom template cell bude nejspíš nutné pokaždé znovu projít všechny sourozence až po správný index. Vůbec to není dobrá struktura vstupních dat. Přitom stačilo tak málo... 8.8.2016
  • Taco : @Fos4: Děkuji za příspěvek. Nefunguje to také proto, že když některé prvky vynechám, tak se mi ty position() s indexem rozlezou. Pak je třeba pro [c] position() = 1 8.8.2016

Pro zobrazení všech 5 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.