0

I created an XSLT to create a new structure for an XML document. I have written a couple of XSLTs before, but I'm unsure if this one is valid because when I test it, the structure of the XML does not change.

Any help or suggestions would be greatly appreciated!

XML Doc:

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.demandware.com/xml/impex/catalog/2006-10-31" catalog-id="pfdc-pl-navigation-catalog">
    <header>
        <image-settings>
            <internal-location base-path="/"/>
            <view-types>
                <view-type>large</view-type>
            </view-types>
            <alt-pattern>${productname}</alt-pattern>
            <title-pattern>${productname}</title-pattern>
        </image-settings>
    </header>

    <category category-id="Galénic">
        <display-name xml:lang="x-default">Galénic</display-name>
        <display-name xml:lang="pl-PL">Galénic</display-name>
        <online-flag>true</online-flag>
        <parent>Find_your_product</parent>
        <template/>
        <page-attributes/>
    </category>

    <category category-id="René Furterer">
        <display-name xml:lang="x-default">René Furterer</display-name>
        <display-name xml:lang="pl-PL">René Furterer</display-name>
        <online-flag>true</online-flag>
        <parent>Find_your_product</parent>
        <template/>
        <page-attributes/>
    </category>

    <category-assignment category-id="renefurterer-categories-hair" product-id="PR1357-PL"/>

    <category-assignment category-id="renefurterer-categories-hair" product-id="PR1362-PL"/>

    <category-assignment category-id="renefurterer-categories-hair" product-id="PR1365-PL"/>

</catalog>

This is the XSLT I am trying to apply:

<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:strip-space elements="*"/>

<!-- Identity Transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="catalog">
 <xsl:element name="categories">
 </xsl:element>
</xsl:template>


 <xsl:template match="category">
 <category>
     <xsl:element name="id">
         <xsl:value-of select="@category-id" />
     </xsl:element>

     <xsl:element name="category_name">
         <xsl:value-of select="display-name[@xml:lang='x-default']" />
     </xsl:element>

     <xsl:element name="parent_category">
         <xsl:value-of select="parent" />
     </xsl:element>

 </category>
 </xsl:template>


</xsl:stylesheet>

The end result that I am hoping to achieve is:

<categories>
  <category>
    <id>René Furterer</id>
    <category_name>René Furterer</category_name>
    <parent_category>Find_your_product</parent_category>
  </category>
  <category>
    <id>Galénic</id>
    <category_name>Galénic</category_name>
    <parent_category>Find_your_product</parent_category>
  </category>
</categories>

As mentioned before, any help would be great.

1 Answers1

2

You were missing the fact that your XML has defined a default namespace http://www.demandware.com/xml/impex/catalog/2006-10-31. So the only template matching was the identity template. With the given templates, you can remove it completely.

Taking this into account, your stylesheet will look like this:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cat="http://www.demandware.com/xml/impex/catalog/2006-10-31">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

    <xsl:template match="/cat:catalog">
        <xsl:element name="categories">
            <xsl:apply-templates select="cat:category" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="cat:category">
        <xsl:element name="category">
            <xsl:element name="id">
                <xsl:value-of select="@category-id" />
            </xsl:element>
            <xsl:element name="category_name">
                <xsl:value-of select="cat:display-name[@xml:lang='x-default']" />
            </xsl:element>
            <xsl:element name="parent_category">
                <xsl:value-of select="cat:parent" />
            </xsl:element>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

I did only minor modifications like replacing native elements with xsl:element name="..." to remove namespaces and prefixing element-name's in XPath matches with prefix:element-name to match the appropriate elements.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • Thanks for that! It looks to have done the trick! – Adrian Oteng-Owusu Nov 02 '18 at 06:22
  • *"replacing native elements with `xsl:element name="..."`"* That's a lot of unnecessary work - not to mention the verbosity it adds to the code. You could have simply added `exclude-result-prefixes="cat"` to the header: http://xsltransform.hikmatu.com/nc4NzPT – michael.hor257k Nov 02 '18 at 21:10