简体   繁体   中英

XSLT to create another XML by filtering only those node where tag value equals

I would like to create another XML with the help of XSLT from document sample below. The idea is to take all student where theirs Profile > City is [PNH], whatever their Origin > Address > City is. I knew with the help of XSLT, we can filter out, and copy only those we would like to have in the new XML document.

<?xml version="1.0" encoding="utf-8"?>
<Class>    
    <Student>
        <Profile>
            <Name>G1</Name>
            <City>PNH</City>            
            <RegDate>2020-06-20</RegDate>
        </Profile>
        <Origin>
            <Address>
                <City>REP</City>
            </Address> 
        </Origin>
    </Student>
    <Student>
        <Profile>
            <Name>G4</Name>
            <City>REP</City>            
            <RegDate>2020-06-20</RegDate>
        </Profile>
        <Origin>
            <Address>
                <City>PNH</City>
            </Address> 
        </Origin>
    </Student>    
    <Student>
        <Profile>
            <Name>G3</Name>
            <City>PNH</City>            
            <RegDate>2020-06-20</RegDate>
        </Profile>
        <Origin>
            <Address>
                <City>PNH</City>
            </Address> 
        </Origin>
    </Student>
    <Student>
        <Profile>
            <Name>G5</Name>
            <City>KOS</City>            
            <RegDate>2020-06-20</RegDate>
        </Profile>
        <Origin>
            <Address>
                <City>PNH</City>
            </Address> 
        </Origin>
    </Student>
</Class>

I would like to take only those student where Profile -> City equals 'PNH' which is final XML result should be

<?xml version="1.0" encoding="utf-8"?>
<Class>    
    <Student>
        <Profile>
            <Name>G1</Name>
            <City>PNH</City>            
            <RegisterDate>2020-06-20</RegisterDate>
        </Profile>
        <Origin>
            <Address>
                <City>REP</City>
            </Address> 
        </Origin>
    </Student>   
    <Student>
        <Profile>
            <Name>G3</Name>
            <City>PNH</City>            
            <RegisterDate>2020-06-20</RegisterDate>
        </Profile>
        <Origin>
            <Address>
                <City>PNH</City>
            </Address> 
        </Origin>
    </Student>
</Class>

I have tried this but it still get all student, but remove data in Profile Tag where City is not PNH

<xsl:template match="@*|node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="Profile[not(City = 'PNH')]"/>

If you want to exclude Student s that satisfy a condition, then your template must match the Student element:

<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="Student[not(Profile/City = 'PNH')]"/>

</xsl:stylesheet>

Alternatively, you could do simply:

<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:template match="/Class">
    <xsl:copy>
        <xsl:copy-of select="Student[Profile/City = 'PNH']"/>
    </xsl:copy>
</xsl:template>

</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