Home > OS >  XSLT remove node with combined condition
XSLT remove node with combined condition

Time:11-24

I can't figure out how to remove parent node if certain conditions are met:

<RSS>
   <ITEM>
      <PRODUCT_ID>75000</PRODUCT_ID>
      <STORAGE>0</STORAGE>
      <VARIANT id="2">
         <ID>75001</ID>
         <STORAGE>1</STORAGE>
      </VARIANT>
      <VARIANT id="3">
         <ID>75002</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
   </ITEM>
   <ITEM>
      <PRODUCT_ID>75100</PRODUCT_ID>
      <STORAGE>0</STORAGE>
      <VARIANT id="2">
         <ID>75101</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
      <VARIANT id="3">
         <ID>75102</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
   </ITEM>
   <ITEM>
      <PRODUCT_ID>75500</PRODUCT_ID>
      <STORAGE>1</STORAGE>
      <VARIANT id="2">
         <ID>75501</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
      <VARIANT id="3">
         <ID>75502</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
   </ITEM>
   <ITEM>
      <ID>75088</ID>
      <STORAGE>1</STORAGE>
   </ITEM>
   <ITEM>
      <ID>75089</ID>
      <STORAGE>0</STORAGE>
   </ITEM>
</RSS>

I would like to remove parent node if:

  • ITEM/STORAGE = 0, but not if ITEM/VARIANT/STORAGE is greater (>) than 0.

Output should be:

<RSS>
   <ITEM>
      <PRODUCT_ID>75000</PRODUCT_ID>
      <STORAGE>0</STORAGE>
      <VARIANT id="2">
         <ID>75001</ID>
         <STORAGE>1</STORAGE>
      </VARIANT>
      <VARIANT id="3">
         <ID>75002</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
   </ITEM>
   <ITEM>
      <PRODUCT_ID>75500</PRODUCT_ID>
      <STORAGE>1</STORAGE>
      <VARIANT id="2">
         <ID>75501</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
      <VARIANT id="3">
         <ID>75502</ID>
         <STORAGE>0</STORAGE>
      </VARIANT>
   </ITEM>
   <ITEM>
      <ID>75088</ID>
      <STORAGE>1</STORAGE>
   </ITEM>
</RSS>

So if ITEM/STORAGE (in this case need to check if it has child VARIANT/STORAGE and is greater than 0) or ITEM/VARIANT/STORAGE is 0, I would like to remove parent node.

CodePudding user response:

I would like to remove parent node if:

ITEM/STORAGE = 0, but not if ITEM/VARIANT/STORAGE is greater (>) than 0.

So the first part (ITEM/STORAGE = 0) translates to this XPath:

ITEM[STORAGE=0]

and the second part (but not if ITEM/VARIANT/STORAGE is greater (>) than 0) translates to:

ITEM[not(VARIANT/STORAGE > 0)]

You can combine them into a single XPath:

ITEM[STORAGE=0][not(VARIANT/STORAGE > 0)]

Combine that with an identity transform (XSLT 1.0/2.0) or an xsl:mode (XSLT 3.0) and you're done...

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="ITEM[STORAGE=0][not(VARIANT/STORAGE > 0)]"/>
    
</xsl:stylesheet>

Fiddle: http://xsltfiddle.liberty-development.net/eiorv18

  • Related