Home > Back-end >  How to remove a tag?
How to remove a tag?

Time:03-10

First xml file "in.xml" to be updated:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11"/>
            <Chartr />
            <Chartu />
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn />
                </d>
                <m5 attr5="gd"/>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto />
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd />
        <m2 />
    </xItem>
</root>

The second xml file "updates.xml" from which data is taken to update the first file:

<updates attr="updates">
    <xItem key="1">
        <b>
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chartr>
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2"/>
                </Widget>
            </Chartu>
            <Itemz key="2">
                <d>
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52"/>
                        </Widget>
                    </Chartn>
                </d>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59"/>
                    </Widget>
                </Charto>
            </Itemt>
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59"/>
            </Widget>
        </Chartd>
    </xItem>
</updates>

XSLT1.0 transformation file, where the ancestors variable contains the first ancestors of the Widget tags from the second "updates.xml" file. Further, when copying the source file, we add data to update from the ancestors variable:

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:variable name="filename" select="'updates.xml'" />
  
  <xsl:variable name="ancestors" select="document('updates.xml')//Widget/ancestor::*[1]" />
  
  <xsl:template match="@*|node()">
    <xsl:variable name="element" select="name()"/>
    
    <xsl:for-each select="$ancestors">
     <xsl:variable name="var" select="local-name()"/> 
      
     <xsl:if test="$element=$var">
        <xsl:copy-of select="(.)"/>
        <xsl:text>&#10;</xsl:text>
     </xsl:if>
     </xsl:for-each> 
          
     <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>  

  </xsl:template>

</xsl:stylesheet>

After transforming the file:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11" />
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6" />
                </Widget>
            </Chartr>
<Chartr />
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2" />
                </Widget>
            </Chartu>
<Chartu />
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52" />
                        </Widget>
                    </Chartn>
<Chartn />
                </d>
                <m5 attr5="gd" />
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59" />
                    </Widget>
                </Charto>
<Charto />
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59" />
            </Widget>
        </Chartd>
<Chartd />
        <m2 />
    </xItem>
</root>

How to remove unnecessary tags 'Chartr', 'Chartu', 'Chartn', 'Charto', 'Chartd' after merging so that there is such a file after transformation:

<root attr="root">
    <xItem key="1">
        <m1 />
        <b attr3="j" attr4="x">
            <m4 />
            <m3 attr4="11"/>
            <Chartr>
                <Widget title="widget54">
                    <Test title="test6"/>
                </Widget>
            </Chartr>
            <Chartu>
                <Widget title="widget78">
                    <Test title="test2"/>
                </Widget>
            </Chartu>
            <Itemz key="2">
                <d>
                    <m6 />
                    <Chartn>
                        <Widget title="widget12">
                            <Test title="test52"/>
                        </Widget>
                    </Chartn>
                </d>
                <m5 attr5="gd"/>
            </Itemz>
        </b>
        <Itemq key="3">
            <Itemt key="4">
                <Charto>
                    <Widget title="widget72">
                        <Test title="test59"/>
                    </Widget>
                </Charto>
                <m6 />
            </Itemt>
            <m7 />
        </Itemq>
        <Chartd>
            <Widget title="widget72">
                <Test title="test59"/>
            </Widget>
        </Chartd>
        <m2 />
    </xItem>
</root>

CodePudding user response:

Perhaps something like this suffices:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exslt="http://exslt.org/common"
  exclude-result-prefixes="exslt"
  version="1.0">
  
  <xsl:key name="replacement" match="*[Widget]" use="local-name()"/>
  
  <xsl:output method="xml"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="*[not(node())]">
    <xsl:variable name="this" select="."/>
    <xsl:variable name="replacement">
      <xsl:for-each select="$updates">
        <xsl:copy-of select="key('replacement', local-name($this))"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="exslt:node-set($replacement)/*">
        <xsl:copy-of select="$replacement"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:param name="updates" select="document('updates.xml')"/>

</xsl:stylesheet>
  • Related