Home > Software design >  XSLT transform XML file | select some tags and convert as description
XSLT transform XML file | select some tags and convert as description

Time:01-31

input XML:

<Products>
    <Product id="ADEDEWADE0009" name="Akumulator DeWalt XR DCB184-XJ (Li-Ion)" producer="DEW" categoryId="ADE-ADE" warranty="F012M" priceNet="234.00" vat="23" vat_type="zwykły" pkwiu="27.20.23.0" externalWarehouse="N" available="30" date="2018-06-08" onOrder="N" specialOffer="N" smallPallet="N" productIsLarge="N" reported="T" EAN="5035048466933" manufacturerPartNumber="DCB184-XJ" sizeWidth="90" sizeLength="75" sizeHeight="130" weight="672" sizeMeasurementUnit="mm" weightMeasurementUnit="g" dimensionalWeight="175" additionalAvailabilityInfo="" expiryDate="1900-01-01" ETA="" incomingStock="0" mainCategoryTree="Dom, Warsztat i Ogród" categoryTree="Narzędzia - osprzęt" subCategoryTree="Akumulatory">
        <Images>
            <Image url="/Icecat/O2N59732L0C0C1V6o7K4N143m7O7K7A8.jpg" isMain="0" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/I4B7m9t9K000X1b6w7V471A3H7R737c8.jpg" isMain="0" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/O9P0t7g7k0k0E1s6H7O4u1R3H7c757V9.jpg" isMain="1" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/I1P2w3a2c0r0N116X7E4P1a3n7l7w7q9.jpg" isMain="0" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/T9X096A3D0D0T1d6A7h481i3B7P7A8L0.jpg" isMain="0" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/Q1D233T3K020Z10607c421L3N7Z7Q8n1.jpg" isMain="0" date="2023-01-19" copyright="0" />
            <Image url="/Icecat/Z2X2z2e5s03031B6G7r4j1Z2W4C9B926.jpg" isMain="0" date="2023-01-19" copyright="0" />
        </Images>
        <Multimedia />
        <TechnicalSpecification>
            <Section name="Cechy">
                <Attributes>
                    <Attribute name="Kolor produktu">
                        <Values>
                            <Value Name="Czarny" />
                            <Value Name="Żółty" />
                        </Values>
                    </Attribute>
                    <Attribute name="Wymiary otworu (dł.*szer.*wys.)"
                        <Values>
                            <Value Name="DeWALT" />
                        </Values>
                    </Attribute>
                    <Attribute name="Napięcie baterii">
                        <Values>
                            <Value Name="18 V" />
                        </Values>
                    </Attribute>
                    <Attribute name="Rodzaj baterii">
                        <Values>
                            <Value Name="Litowo-jonowa (Li-Ion)" />
                        </Values>
                    </Attribute>
                </Attributes>
            </Section>
        </TechnicalSpecification>
    </Product>

part XSLT code:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">
  
  <xsl:output method="text"/>
  
  <xsl:variable name="first-step-result">
    <xsl:apply-templates/>
  </xsl:variable>
  
  <xsl:variable name="dynamic-elements" select="$first-step-result//*[starts-with(local-name(), 'Image_extra')]"/>
  <xsl:variable name="cdata-section-elements" select="$dynamic-elements/node-name()"/>
  
  <xsl:template match="/">
    <xsl:value-of select="serialize($first-step-result, map { 'method' : 'xml', 'indent': true(), 'cdata-section-elements' : $cdata-section-elements })"/>
  </xsl:template>


    <xsl:template match="Products">
      <xsl:copy>
        <xsl:apply-templates select="Product"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Product">
      <xsl:copy>
        <xsl:for-each select="@*">
          <xsl:element name="{name()}">
              <xsl:value-of select="."/>
          </xsl:element>
        </xsl:for-each>
        <xsl:apply-templates select="Images/Image"/>
        <xsl:apply-templates select="TechnicalSpecification/Section/Attributes/Attribute"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Image[@isMain='1']">
      <Image_main>
        <xsl:value-of select="@url"/>
      </Image_main>
    </xsl:template>
    
    <xsl:template match="Image[@isMain='0']">
      <xsl:element name="{concat('Image_extra_',position())}">
        <xsl:value-of select="@url"/>
      </xsl:element>
    </xsl:template>

<!-- attributes start from here -->


</xsl:stylesheet>

I try select content from <Section name="Cechy"> </section> and

<Section name="Cechy">
                <Attributes>
                    <Attribute name="Kolor produktu">
                        <Values>
                            <Value Name="Czarny" />
                            <Value Name="Żółty" />
                        </Values>
                    </Attribute>
                    <Attribute name="Wymiary otworu (dł.*szer.*wys.)"
                        <Values>
                            <Value Name="DeWALT" />
                        </Values>
                    </Attribute>
                    <Attribute name="Napięcie baterii">
                        <Values>
                            <Value Name="18 V" />
                        </Values>
                    </Attribute>
                    <Attribute name="Rodzaj baterii">
                        <Values>
                            <Value Name="Litowo-jonowa (Li-Ion)" />
                        </Values>
                    </Attribute>
                </Attributes>
            </Section>

transform to, try get output XML for attributes parts XML some like:

    <description>
    <table border="1" style="border-collapse: collapse; width: 100%; height: 160px;">
<tbody>
    <tr>
    <td>Kolor produktu: Czarny, żółty</td>
</tr>
<tr>
    <td>Wymiary otworu (dł.*szer.*wys.): DeWALT</td>
</tr>
<tr>
    <td>Napięcie baterii: 18 V</td>
</tr>
<tr>
    <td>Rodzaj baterii: Litowo-jonowa (Li-Ion)</td>
    </tr>
    </table>
     </description>

I'm new to this, and it's not my field at all. I will be grateful for any help. And from this place I also wanted to thank the people who helped me build this code and achieve the expected effect.

CodePudding user response:

This is straight-forward input/output mapping e.g.

<xsl:template match="Section">
  <description>
   <xsl:apply-templates/>
  </description>
</xsl:template>

<xsl:template match="Attributes">
  <table>
   <tr>
    <xsl:apply-templates/>
   </tr>
  </table>
</xsl:template>

<xsl:template match="Attribute" expand-text="yes">
  <td>{@name}: {string-join(Values/Value/@Name, ', ')}</td>
</xsl:template>

plus obviously making sure you process Sections in e.g. <xsl:template match="Product"> by changing <xsl:apply-templates select="TechnicalSpecification/Section/Attributes/Attribute"/> to <xsl:apply-templates select="TechnicalSpecification/Section"/>.

You have edited your required output a bit but I would think you can add the tbody and the table attributes on your own.

  • Related