简体   繁体   中英

XSLT: How to exclude a node in XML based on attribute value?

From below input XML, i first need to exclude nodes with empty education details node. And i could achieve it by doing <xsl:template match="parent/child[education = '']"/> . Now from the returned results, i need to remove namedetails node when test1 value in it does not match with child/name/lastname . I should apply this only on XML data i get from removing empty education node. When i try using <xsl:template match="parent/namedetails[test1 = parent/child/name[@lastname]]"/> , it does not filter as i expected. Instead includes all namedetails node. Please suggest.

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <namedetails>
        <test1>xyz</test1>
        <test2>match1</test2>
    </namedetails>
    <child>
        <age>30</age>
        <name>
            <firstname>abc</firstname>
            <lastname>xyz</lastname>
            <middlename>v</middlename>
        </name>
        <education>
            <graduate>Yes</graduate>
            <masters>No</masters>
        </education>
        <dob>25-MAR-1990</dob>
        <location>city123</location>        
    </child>
    <namedetails>
        <test1>123</test1>
        <test2>match2</test2>
    </namedetails>    
    <child>
        <age>29</age>
        <name>
            <firstname>def</firstname>
            <lastname>123</lastname>
            <middlename>a</middlename>
        </name>
        <education/>
        <dob>25-MAR-1991</dob>
        <location>city123</location>        
    </child>
    <namedetails>
        <test1>345w</test1>
        <test2>match3</test2>
    </namedetails>     
    <child>
        <age>35</age>
        <name>
            <firstname>ghi</firstname>
            <lastname>345</lastname>
            <middlename>r</middlename>
        </name>
        <education>
            <graduate>Yes</graduate>
            <masters>Yes</masters>
        </education>
        <dob>25-MAR-1985</dob>
        <location>city123</location>        
    </child>
</parent>

Desired Output XML:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <namedetails>
        <test1>xyz</test1>
        <test2>match1</test2>
    </namedetails>
    <child>
        <age>30</age>
        <name>
            <firstname>abc</firstname>
            <lastname>xyz</lastname>
            <middlename>v</middlename>
        </name>
        <education>
            <graduate>Yes</graduate>
            <masters>No</masters>
        </education>
        <dob>25-MAR-1990</dob>
        <location>city123</location>        
    </child>

    <namedetails>
        <test1>345w</test1>
        <test2>match3</test2>
    </namedetails>     
    <child>
        <age>35</age>
        <name>
            <firstname>ghi</firstname>
            <lastname>345</lastname>
            <middlename>r</middlename>
        </name>
        <education>
            <graduate>Yes</graduate>
            <masters>Yes</masters>
        </education>
        <dob>25-MAR-1985</dob>
        <location>city123</location>        
    </child>
</parent>

XSLT used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/> 

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

<xsl:template match="parent/child[education = '']"/>
<xsl:template match="parent/namedetails[test1 = parent/child/name[@lastname]]"/>
</xsl:stylesheet>

Obtained Ouput:

<parent>
      <namedetails>
            <test1>xyz</test1>
            <test2>match1</test2>
      </namedetails>
      <child>
            <age>30</age>
            <name>
                  <firstname>abc</firstname>
                  <lastname>xyz</lastname>
                  <middlename>v</middlename>
            </name>
            <education>
                  <graduate>Yes</graduate>
                  <masters>No</masters>
            </education>
            <dob>25-MAR-1990</dob>
            <location>city123</location>        
      </child>
      <namedetails>
            <test1>123</test1>
            <test2>match2</test2>
      </namedetails>    

      <namedetails>
            <test1>345w</test1>
            <test2>match3</test2>
      </namedetails>     
      <child>
            <age>35</age>
            <name>
                  <firstname>ghi</firstname>
                  <lastname>345</lastname>
                  <middlename>r</middlename>
            </name>
            <education>
                  <graduate>Yes</graduate>
                  <masters>Yes</masters>
            </education>
            <dob>25-MAR-1985</dob>
            <location>city123</location>        
      </child>
</parent>

@Veena - I don't know what exactly you required output. But i think you will get output like i have done here please try this way.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output indent="yes"/>

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

<xsl:template match="parent">
    <parent>
        <xsl:for-each select="namedetails">
            <xsl:if test="./test1=following-sibling::child[1]/name/lastname">
                <xsl:apply-templates select="."/>
            </xsl:if>
            <xsl:apply-templates select="following-sibling::child[1]"/>
        </xsl:for-each>
    </parent>
</xsl:template>

here is the precise code for your requirement.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>     
<xsl:template match="@* | node()">
  <xsl:copy>
     <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match= "parent/namedetails[following-sibling::[1][education = ''] and 
                      test1=following-sibling::[1]/name/lastname]"/>
<xsl:template match="parent/child[education = '']"/>

</xsl:stylesheet>

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