2
votes

I just need to transform one XML file to another XML file with the wanted data. The transformation remove every parent nodes if child nodes doesn't contain the correct category.

Input XML:

    <SHOP>
    <SHOPITEM>
        <ITEM_ID>142</ITEM_ID>
        <PRODUCT>Mora MV 1251</PRODUCT>
        <DESCRIPTION>XXXXX</DESCRIPTION>
        <URL>http://www.xxx.sk/o</URL>
        <IMGURL>http://xxx.jpg</IMGURL>
        <PRICE>6.74</PRICE>
        <PRICE_VAT>8.10</PRICE_VAT>
        <VAT>0.20</VAT>
        <MANUFACTURER>Mora</MANUFACTURER>
        <CATEGORYTEXT>Accessories / Mobile</CATEGORYTEXT>
        <EAN>8590371028526</EAN>
        <PRODUCTNO></PRODUCTNO>
        <WARRANTY>24</WARRANTY>
        <DELIVERY_DATE>24</DELIVERY_DATE>
    </SHOPITEM>

    <SHOPITEM>
       <ITEM_ID>XXX</ITEM_ID>
       <PRODUCT>Hyundai LLF 22924 DVDR</PRODUCT>
       <DESCRIPTION>XXXXX</DESCRIPTION>
       <URL>http://www.xxx.sk/t</URL>
       <IMGURL>http://xxx.jpg</IMGURL>
       <PRICE>173.35</PRICE>
       <PRICE_VAT>208.00</PRICE_VAT>
       <VAT>0.20</VAT>
       <MANUFACTURER>Hyundai</MANUFACTURER>
       <CATEGORYTEXT>Main category / TVs</CATEGORYTEXT>
       <EAN>xxxxx</EAN>
       <PRODUCTNO/>
       <WARRANTY>24</WARRANTY>
       <DELIVERY_DATE>99999</DELIVERY_DATE>
    </SHOPITEM>
    </SHOP>

I need to remove every SHOPITEM nodes where the CATEGORYTEXT is not Main category / TVs

I have the below XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

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

 <xsl:template match="CATEGORYTEXT[not(text() = 'Main category / TVs')]"/>
</xsl:stylesheet>

But this only removes the CATEGORYTEXT node, not the full SHOPITEM node. Can anyone help me please? :) I'm new too XSLT, every help is appreciated.

Desired output is:

       <SHOP>
         <SHOPITEM>
           <ITEM_ID>XXX</ITEM_ID>
           <PRODUCT>Hyundai LLF 22924 DVDR</PRODUCT>
           <DESCRIPTION>XXXXX</DESCRIPTION>
           <URL>http://www.xxx.sk/t</URL>
           <IMGURL>http://xxx.jpg</IMGURL>
           <PRICE>173.35</PRICE>
           <PRICE_VAT>208.00</PRICE_VAT>
           <VAT>0.20</VAT>
           <MANUFACTURER>Hyundai</MANUFACTURER>
           <CATEGORYTEXT>Main category / TVs</CATEGORYTEXT>
           <EAN>xxxxx</EAN>
           <PRODUCTNO/>
           <WARRANTY>24</WARRANTY>
           <DELIVERY_DATE>99999</DELIVERY_DATE>
         </SHOPITEM>
       </SHOP>
1

1 Answers

3
votes

Replace this

<xsl:template match="CATEGORYTEXT[not(text() = 'Main category / TVs')]"/>

with this:

<xsl:template match="SHOPITEM[not(CATEGORYTEXT = 'Main category / TVs')]"/>

Your current template filters CATEGORYTEXT elements based on the value of their text node children, whereas what you need is to filter SHOPITEM elements based on the value of their CATEGORYTEXT element children.

Note that it is only very rarely that you actually need to use text() in an XPath expression - text() gives you a set of all the individual text nodes that are direct children of the element you're dealing with, whereas usually what you care about is the complete string value of the element itself (which is, by definition, the concatenation of all its descendant text nodes)