Search code examples
xslt

XSLT remove node depending on language context


I'm having trouble on applying a stylesheet for the following problem: This is my given XML-file:

<?xml version="1.0" encoding="UTF-8"?>

<STEP-ProductInformation>
  <Products>
    <Product ID="prd_ProdVar-286244">
      <Values>
        <ValueGroup AttributeID="tec_att_ignore_basic_data_text" ID="Y">
          <Value ID="Y" LOVQualifierID="en-US">Yes</Value>
          <Value ID="Y" LOVQualifierID="std.lang.all">Yes</Value>
          <Value ID="N" LOVQualifierID="de-DE">Ja</Value>
        </ValueGroup>
        <Value AttributeID="prd_att_description" Inherited="1" QualifierID="de-DE">
            Some text in german
        </Value>
        <Value AttributeID="prd_att_description" Inherited="5" QualifierID="en-US">
            Some text in english
        </Value>
    </Product>
  </Products>
</STEP-ProductInformation>

As you can see, I have a ValueGroup with (in this case) Y and N, which means, I wanna remove all prd_att_description from my final file which relate to the qualifierID where there is an "Y" representing it. If the LOVQualifierID is equal to N like in the german case, that Attribute should be kept.

I did try figuring it out and ended up with this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@prd_att_description[../@tec_att_ignore_basic_data_text = 'Y']"/>
</xsl:stylesheet>

but that is obviously wrong, since it doesn't take into consideration what context is nor does it delete the nodes anyway.

Expected output:

<?xml version="1.0" encoding="UTF-8"?>

<STEP-ProductInformation>
  <Products>
    <Product ID="prd_ProdVar-286244">
      <Values>
        <ValueGroup AttributeID="tec_att_ignore_basic_data_text" ID="Y">
          <Value ID="Y" LOVQualifierID="en-US">Yes</Value>
          <Value ID="Y" LOVQualifierID="std.lang.all">Yes</Value>
          <Value ID="N" LOVQualifierID="de-DE">Ja</Value>
        </ValueGroup>
        <Value AttributeID="prd_att_description" Inherited="1" QualifierID="de-DE">
            Some text in german
        </Value>
        <!-- english part stripped/removed -->
    </Product>
  </Products>
</STEP-ProductInformation>

As you can see: since the value-ID of <Value ID="N" LOVQualifierID="de-DE">Ja</Value> is N in german, it is kept. English has a Y and is thus removed.

Any help appreciated


Solution

  • I am having trouble following your description of the logic that needs to be applied here. Is it possible that what you want to do is actually:

    XSLT 1.0

    <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="*"/>
    
    <xsl:key name="lov" match="ValueGroup[@AttributeID='tec_att_ignore_basic_data_text']/Value" use="@LOVQualifierID" />
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Value[@AttributeID='prd_att_description'][key('lov', @QualifierID)/@ID='Y']"/>
        
    </xsl:stylesheet>
    

    When this stylesheet processes a Value whose AttributeID is "prd_att_description", it looks up the related Value from the ValueGroup whose AttributeID is "tec_att_ignore_basic_data_text", using a key to match the QualifierID attribute to the LOVQualifierID attribute. If the matched Value's ID is "Y", the processed Value is removed.