Home > Net >  XSLT - how to remove certain elements from XML structure
XSLT - how to remove certain elements from XML structure

Time:04-24

Am new to the world of XSLT and am facing issues with how to go about it I have following XML:

    <?xml version="1.0" encoding="utf8" ?>
<Output>
    <Error>
        <Status>0</Status>
        <Details>No errors</Details>
    </Error>
    <Synopsis>
        <Count>451</Count>
    </Synopsis>
    <BankAccounts>
        <BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
            <Addresses>
                <Address>ABC</Address>
                <Address>XYZ</Address>
            </Addresses>
        </BankAccount>
        <BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
            <Addresses>
                <Address>LMN</Address>
                <Address>QWE</Address>
            </Addresses>
        </BankAccount>
        
    </BankAccounts>
</Output>

I need to convert it to :

<BankAccounts>
    <BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
        <Addresses>
            <Address>ABC</Address>
            <Address>XYZ</Address>
        </Addresses>
    </BankAccount>
    <BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
        <Addresses>
            <Address>LMN</Address>
            <Address>QWE</Address>
        </Addresses>
    </BankAccount>
    
</BankAccounts>

I tried applying following XSLT :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <!-- Identity template, copies everything as is -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>    
    
    <xsl:template match="Output/Error">
        <xsl:apply-templates/>
    </xsl:template>    
   
</xsl:stylesheet>

However I get the exception :

net.sf.saxon.trans.XPathException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 8; The processing instruction target matching "[xX][mM][lL]" is not allowed.

CodePudding user response:

Just use a xsl:copy-of ... of the relevant element and mask the text() nodes which would be copied by the Built-in template rules like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

  <xsl:template match="text()" />
  
  <xsl:template match="/Output">
    <xsl:copy-of select="BankAccounts"/>
  </xsl:template>

</xsl:stylesheet>

Its output is as desired:

<?xml version="1.0"?>
<BankAccounts>
    <BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1">
        <Addresses>
            <Address>ABC</Address>
            <Address>XYZ</Address>
        </Addresses>
    </BankAccount>
    <BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1">
        <Addresses>
            <Address>LMN</Address>
            <Address>QWE</Address>
        </Addresses>
    </BankAccount>
</BankAccounts>

CodePudding user response:

Or simply:

<xsl:stylesheet version="2.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="*"/>

<xsl:template match="/Output">
    <xsl:copy-of select="BankAccounts"/>
</xsl:template>

</xsl:stylesheet>
  • Related