0

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>
2
  • 1
    The proper way to output the text of some elements using CDATA sections is to specify the names of those elements in a cdata-section-elements attribute of xsl:output. However, since in your case you do not know the names of those elements in advance, that's not possible and you need to resort to using a hack - which may or may not work, depending on your processor. See an example here: stackoverflow.com/a/61842043/3016153 Commented Jan 28, 2023 at 18:12
  • 1
    P.S. Please ask one question at a time. Commented Jan 28, 2023 at 18:14

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

8 Comments

I dont know why, but everytime we have still issue with this attributes :(
<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="Kompatybilność z marką"><Values><Value Name="DeWALT" /></Values></Attribute></Attributes> - this is example
When I try transform: prnt.sc/4tqlrW-XG2qV
@user20508390, I have edited the answer to add the space character ' ' to the sequence of characters to be converted by the translate function to an _ character.
I really appreciate your help on a high level. Everything works fine, but we have a main problem with the name of the attributes. I spent two hours yesterday manually removing special characters with replace in xml and it seems endless. Example: <Attribute name="Funkcja Hob²Hood"> or <Attribute name="Czas osiągnięcia 100°C"> or <Attribute name="Czas osiągnięcia & osiągnięcia"> <Attribute name="Czas osiągnięcia:nb;osiągnięcia"> etc.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.