简体   繁体   中英

Delete a tag from XML file using XSLT if another tag is empty

I am not sure how to write an XSLT for this.

This is my XML file

<?xml version="1.0" encoding="UTF-8"?>
<people>
<person>
    <firstname>Mike</firstname>
    <lastname>Hewitt</lastname>
    <licenses/>
    <license-details>
        <tag1>xyz</tag1>
    </license-details>
</person>
<person>
    <firstname>Mike</firstname>
    <lastname>Hewitt</lastname>
    <licenses>
        <state>NY</state>
    </licenses>
    <license-details>
        <tag1>xyz</tag1>
    </license-details>
</person>
</people>

What I am trying to achieve is that, I want to delete license-details tag, if licenses tag is empty

This is how the output should be:

<?xml version="1.0" encoding="UTF-8"?>
<people>
<person>
    <firstname>Mike</firstname>
    <lastname>Hewitt</lastname>
</person>
<person>
    <firstname>Mike</firstname>
    <lastname>Hewitt</lastname>
    <licenses>
        <state>NY</state>
    </licenses>
    <license-details>
        <tag1>xyz</tag1>
    </license-details>
</person>
</people>

Can someone guide me how to write an XSLT for this, I am using XSLT version 1.0

One way you could delete the nodes would be as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"  
                omit-xml-declaration="no" 
                encoding="UTF-8" indent="yes" />
    <xsl:strip-space  elements="*"/>
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="licenses[count(node())=0] | 
                license-details[count(./preceding-sibling::licenses/node())=0]"/>
</xsl:stylesheet>

XML Output:

<?xml version="1.0" encoding="UTF-8"?>
<people>
   <person>
     <firstname>Mike</firstname>
     <lastname>Hewitt</lastname>
   </person>
   <person>
     <firstname>Mike</firstname>
     <lastname>Hewitt</lastname>
     <licenses>
       <state>NY</state>
     </licenses>
     <license-details>
       <tag1>xyz</tag1>
     </license-details>
   </person>
</people>

The last template matches all licenses without child nodes - licenses[count(node())=0] - and all license-details that have a preceding sibling licenses without any child nodes - license-details[count(./preceding-sibling::licenses/node())=0] . Because this empty template produces no output, both won't be written to the output.

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM