Home > database >  XSLT to XML transform | add url and CDATA to tags
XSLT to XML transform | add url and CDATA to tags

Time:01-29

This is original XML file content:

<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>

with this XSLT:

<?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>

I get transform and get output:

  <Image_main>/Icecat/19G8R4l3c0x0b196V7h4J2D1N4F7S0L0.jpg</Image_main>
  <Image_extra_1>/Icecat/D3E6P3e1I030F1l667A442I1c4W7z0i3.jpg</Image_extra_1>
  <Image_extra_2>/Icecat/I742p4F4R020U1w6h784e2b1s4d7W094.jpg</Image_extra_2>
  <Image_extra_3>/Icecat/55G1s3Z3u090I196C7K4J2H1b4d7o074.jpg</Image_extra_3>
  <Image_extra_4>/Icecat/I0L4q4X5l0O021o6k7D4k2a1t457U0F5.jpg</Image_extra_4>

Cananyone help me how to during transform:

add to this tags images <![CDATA[ ]]>

and one url websites before /Icekat to get path to full website image.

except result:

  <Image_main><![CDATA[https://anyweb.com/Icecat/19G8R4l3c0x0b196V7h4J2D1N4F7S0L0.jpg]]></Image_main>
  <Image_extra_1>[CDATA[https://anyweb.com/Icecat/D3E6P3e1I030F1l667A442I1c4W7z0i3.jpg]]></Image_extra_1>

CodePudding user response:

In XSLT 3 you could easily do both transformation steps in one stylesheet and that way generate the right serialization options on the fly e.g.

<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>
    
    <xsl:template match="Attribute">
      <xsl:element name="{translate(@name,'()', '__')}">
        <xsl:value-of select="Values/Value/@Name"/>
      </xsl:element>
    </xsl:template>
  
</xsl:stylesheet>

XSLT 3 is available with Saxon 9.8 and later (available in the open-source HE edition for Java and .NET framework, available also as SaxonC HE for C/C /Python/PHP), SaxonJS 2 for client and server-side JavaScript.

  • Related