Home > Software engineering >  in a XML, how to remove one complete node if the text of the grandchilds are not the same, with XSLT
in a XML, how to remove one complete node if the text of the grandchilds are not the same, with XSLT

Time:07-21

I have this XML from which I want to remove all nodes that do not comply with having equal texts in their grandchilds elements, detailed information after the input XML.

The input XML:

<COMPANY>   
    <SCHEDULES>
        <OFFICE name="BCO">
            <DEPARTAMENT name="BCO1">
                <days>monday:friday</days>
                <code>Y</code>
                <indice>0</indice>
            </DEPARTAMENT>
            <TEAM name="BCO2">
                <days>monday:friday</days>
                <code>I</code>
                <indice>0</indice>
            </TEAM>
        </OFFICE>
        <OFFICE name="RCO">
            <DEPARTAMENT name="RCO1">
                <days>monday:tuesday</days>
                <code>Y</code>
                <indice>0</indice>
            </DEPARTAMENT>
            <TEAM name="RCO2">
                <days>monday:wednesday</days>
                <code>t</code>
                <indice>0</indice>
            </TEAM>
        </OFFICE>
        <OFFICE name="LCO">
            <DEPARTAMENT name="LCO1">
                <days>wednesday:saturday</days>
                <code>Y</code>
                <indice>0</indice>
            </DEPARTAMENT>
            <TEAM name="LCO2">
                <days>wednesday:saturday</days>
                <code>In</code>
                <indice>0</indice>
            </TEAM>
        </OFFICE>
        <OFFICE name="ACO">
            <DEPARTAMENT name="ACO1">
                <days>monday</days>
                <code>a</code>
                <indice>1</indice>
            </DEPARTAMENT>
            <TEAM name="ACO2">
                <days>tuesday</days>
                <code>a</code>
                <indice>1</indice>
            </TEAM>
        </OFFICE>
    </SCHEDULES>
</COMPANY>

I want to delete all the element OFFICE, if the text of the days tag inside DEPARTAMENT and TEAM, are not the same, that way I would have an output like this :

<COMPANY>   
    <SCHEDULES>
        <OFFICE name="BCO">
            <DEPARTAMENT name="BCO1">
                <days>monday:friday</days>
                <code>Y</code>
                <indice>0</indice>
            </DEPARTAMENT>
            <TEAM name="BCO2">
                <days>monday:friday</days>
                <code>I</code>
                <indice>0</indice>
            </TEAM>
        </OFFICE>
        <OFFICE name="LCO">
            <DEPARTAMENT name="LCO1">
                <days>wednesday:saturday</days>
                <code>Y</code>
                <indice>0</indice>
            </DEPARTAMENT>
            <TEAM name="LCO2">
                <days>wednesday:saturday</days>
                <code>In</code>
                <indice>0</indice>
            </TEAM>
        </OFFICE>
    </SCHEDULES>
</COMPANY>

Im trying to use this XSLT but I have an error for the XPath expression.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" 
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="//SCHEDULES/OFFICE/DEPARTAMENT/days[text()]=//SCHEDULES/OFFICE/TEAM/days[text()]"/>

</xsl:stylesheet>

How can I do this using XSLT 1.0, thank you for any answers that may help

CodePudding user response:

I think you want to do:

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="*"/>

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

<xsl:template match="OFFICE[DEPARTAMENT/days != TEAM/days]"/>

</xsl:stylesheet>

Applied to your example input, this will return:

Result

<?xml version="1.0" encoding="UTF-8"?>
<COMPANY>
  <SCHEDULES>
    <OFFICE name="BCO">
      <DEPARTAMENT name="BCO1">
        <days>monday:friday</days>
        <code>Y</code>
        <indice>0</indice>
      </DEPARTAMENT>
      <TEAM name="BCO2">
        <days>monday:friday</days>
        <code>I</code>
        <indice>0</indice>
      </TEAM>
    </OFFICE>
  </SCHEDULES>
</COMPANY>

This is different from the result you show - but the result you show makes no sense, because <OFFICE name="LCO"> has different data than the source.

To understand how this works, you should learn about predicates.

  • Related