XPath that excludes some part of selected element?

XPath's great for selecting but not for structuring. Step up to full XSLT for both. A simple identity-based transformation is all you need...

Given this XML input:

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <rows>
    <row hash="156458">
      <column name="Id">1</column>
      <column name="Nome">Evandro</column>
      <column name="CPF">98765432100</column>
    </row>
    <row hash="52458">
      <column name="Id">2</column>
      <column name="Nome">Everton</column>
      <column name="CPF">12345678900</column>
    </row>
  </rows>
</root>

This XSLT transformation:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="column[@name='Id']"/>

</xsl:stylesheet>

Will produce the desired XML output:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <rows>
      <row hash="156458">
         <column name="Nome">Evandro</column>
         <column name="CPF">98765432100</column>
      </row>
      <row hash="52458">
         <column name="Nome">Everton</column>
         <column name="CPF">12345678900</column>
      </row>
   </rows>
</root>

Notes:

  • The first template is the identify template; it will copy nodes from input to output unless a more specific template overrides it.
  • The second template is an override to omit Id columns.