Home > Blockchain >  XSLT to XML - how to convert attributes to tags and num tags
XSLT to XML - how to convert attributes to tags and num tags

Time:01-27

I need to convert this XML file to standard XML with tags like <id>1</id>

XML original file code:

 <Products>
<!-- FIRST PART -->
    <Product id="ADEBLDADE0001" name="Black  Decker BL4018 Battery" producer="BLD" categoryId="ADE-ADE" warranty="F012M" priceNet="43.95" vat="23" vat_type="zwykły" pkwiu="27.20.23.0" externalWarehouse="N" available="30" date="2017-03-13" onOrder="N" specialOffer="N" lastChange="2022-10-17" smallPallet="N" productIsLarge="N" reported="T" EAN="5035048560044" manufacturerPartNumber="BL4018-XJ" sizeWidth="80" sizeLength="130" sizeHeight="110" weight="690" sizeMeasurementUnit="mm" weightMeasurementUnit="g" dimensionalWeight="228" additionalAvailabilityInfo="" expiryDate="1900-01-01" ETA="" incomingStock="0" mainCategoryTree="House and Garden" categoryTree="Tools - accessories" subCategoryTree="Batteries">
<!-- SECOND PART -->
    <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>
<!-- THIRD PART -->
    <Multimedia/>
    <TechnicalSpecification>
    <Section name="Features">
    <Attributes>
    <Attribute name="Product type">
    <Values>
    <Value Name="Battery"/>
    </Values>
    </Attribute>
    <Attribute name="Battery technology">
    <Values>
    <Value Name="Lithium-Ion (Li-Ion)"/>
    </Values>
    </Attribute>
    <Attribute name="Battery capacity">
    <Values>
    <Value Name="2 Ah"/>
    </Values>
    </Attribute>
    <Attribute name="Battery voltage">
    <Values>
    <Value Name="18 V"/>
    </Values>
    </Attribute>
    <Attribute name="Product colour">
    <Values>
    <Value Name="Grey"/>
    <Value Name="Black"/>
    <Value Name="Orange"/>
    </Values>
    </Attribute>
    <Attribute name="Number of batteries included">
    <Values>
    <Value Name="1 pc(s)"/>
    </Values>
    </Attribute>
    </Attributes>
    </Section>
    </TechnicalSpecification>
    </Product>
    </Products>

Except result similar to:

<Products>
<product>
    <id>ADEBLDADE0001</id>
    <name>Black  Decker BL4018 Battery</name>
    <producer>BLD</producer>
    <categoryId>ADE-ADE</categoryId>
    <warranty>F012M</warranty> 
    <priceNet>43.95</priceNet> 
    <vat>23</vat> 
    <vat_type>zwykły</vat_type> 
    <pkwiu>27.20.23.0</pkwiu> 
    <externalWarehouse>="N"</externalWarehouse> 
    <available>30</available> 
    <date>2017-03-13</date>
     <onOrder>N</onOrder> 
    <specialOffer>N</specialOffer>
     <lastChange>2022-10-17</lastChange> 
     <smallPallet>N</smallPallet>
     <productIsLarge>N</productIsLarge>
     <reported>T</reported> 
     <EAN>5035048560044</EAN> 
     <manufacturerPartNumber>BL4018-XJ</manufacturerPartNumber>
     <sizeWidth>80</sizeWidth>
     <sizeLength>130</sizeLength>
     <sizeHeight>110</sizeHeight>
     <weight>690</weight>
     <sizeMeasurementUnit>mm</sizeMeasurementUnit>
     <weightMeasurementUnit>g"</weightMeasurementUnit>
     <dimensionalWeight>228</dimensionalWeight>
     <additionalAvailabilityInfo> </additionalAvailabilityInfo>
     <expiryDate>1900-01-01</expiryDate>
     <ETA></ETA>
     <incomingStock>0 </incomingStock>
     <mainCategoryTree>House and Garden </mainCategoryTree>
     <categoryTree>Tools - accessories </categoryTree>
     <subCategoryTree>Batteries></subCategoryTree>
    <Image_main>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_main>
    <Image_extra_1>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_1>
    <Image_extra_2>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_2>
    <Image_extra_3>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_3>
    <Image_extra_4>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_4>
    <Image_extra_5>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_5>
    <Image_extra_6>/Icecat/S0p7v4R77040m1G5A8J41445s6v7T2v9.jpg</Image_extra_6>
    <Product_type>Battery</Product_type>
    <Battery_technology>Lithium-Ion (Li-Ion)</Battery_technology>
    <Battery_capacity>2 Ah</Battery_capacity>
    <Battery_voltage>18 V</Battery_voltage>
    <Product_colour>Grey Black Orange</Product_colour>
    <Number_of_batteries_included>1 pc(s)</Number_of_batteries_included>
    </Product>
    </Products>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:g="http://base.google.com/ns/1.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="Products">
        
<xsl:for-each select="Product">
    <Product>
<!-- FIRST PART - (THIS PART WORKING CORRECT)-->
        <xsl:for-each select="@*">
            <xsl:element name="{name()}">
                <xsl:value-of select="."/>
            </xsl:element>
        </xsl:for-each>

<!-- SECOND PART -->
                <xsl:for-each select="Images/image">
                    <xsl:element name="image{position()}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
        
     <!-- THIRD PART START HERE -->
        
    </Product>
</xsl:for-each>
            
    </xsl:template>

</xsl:stylesheet>

Now current output for above code:

    <?xml version="1.0" encoding="UTF-8"?>
        <Product>
    <id>ADEDEWADE0009</id>
    <name>Akumulator DeWalt XR DCB184-XJ (Li-Ion)</name>
    <producer>DEW</producer>
<categoryId>ADE-ADE</categoryId>
<warranty>F012M</warranty>
<priceNet>234.00</priceNet>
<vat>23</vat>
<vat_type>zwykły</vat_type>
<pkwiu>27.20.23.0</pkwiu>
<externalWarehouse>N</externalWarehouse>
<available>30</available>
<date>2018-06-08</date>
<onOrder>N</onOrder>
<specialOffer>N</specialOffer><smallPallet>N</smallPallet><productIsLarge>N</productIsLarge><reported>T</reported><EAN>5035048466933</EAN><manufacturerPartNumber>DCB184-XJ</manufacturerPartNumber><sizeWidth>90</sizeWidth><sizeLength>75</sizeLength><sizeHeight>130</sizeHeight><weight>672</weight><sizeMeasurementUnit>mm</sizeMeasurementUnit><weightMeasurementUnit>g</weightMeasurementUnit><dimensionalWeight>175</dimensionalWeight><additionalAvailabilityInfo/><expiryDate>1900-01-01</expiryDate><ETA/><incomingStock>0</incomingStock><mainCategoryTree>Dom, Warsztat i Ogród</mainCategoryTree><categoryTree>Narzędzia - osprzęt</categoryTree><subCategoryTree>Akumulatory</subCategoryTree>
<image1/>
</Product>

Part1 working correct, but for part 2 I get only tag <image1/>. For the third part code, im not sure how to start.

Can someone help me convert the second part to create links to photos in numbered tags and for the third part convert this attributes with values to tags?

CodePudding user response:

I'm also new to XSLT but the following statements should work:

<!-- SECOND PART -->

<xsl:for-each select=".//Image">
    <xsl:sort select="@isMain" order="descending"/>
    <xsl:choose>
        <xsl:when test="@isMain = 1">
            <Image_main>
                <xsl:value-of select="@url"/>
            </Image_main>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{concat('Image_extra_',position())}">
                <xsl:value-of select="@url"/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>
<!-- THIRD PART -->

<xsl:for-each select=".//Attribute">
    <xsl:element name="{translate(@name,' ','_')}">
        <!--<xsl:value-of select="string-join(.//Value/@Name,' ')"/>-->
        <xsl:for-each select=".//Value/@Name">
            <xsl:if test="position() > 1">
                <xsl:text> </xsl:text>
            </xsl:if>
            <xsl:value-of select="."/>
        </xsl:for-each>
    </xsl:element>
</xsl:for-each>

CodePudding user response:

This transformation applied to your input gives the required output :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <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>
    
    <xsl:template match="Attribute">
      <xsl:element name="{translate(@name,' ','_')}">
        <xsl:value-of select="Values/Value/@Name"/>
      </xsl:element>
    </xsl:template>

</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/gWcBdB9

  • Related