Search code examples
javaxsltjaxbxslt-2.0jaxb2

xslt help - remove empty tags and replaces * with empty tags


I am having a problem while doing some XSLT pre-processing in my java program. We get an asterisk (*) from a mainframe program when it wants to blank out a value, which my java process has to treat like a blank or empty tag. So we apply an xslt to the input before my jaxb process.

We are applying this xslt :

  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no"/>
  <xsl:template match="@*[. = '*']">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
      <xsl:text></xsl:text>
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="*[. = '*']">
    <xsl:copy>
      <xsl:text></xsl:text>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The above xslt works fine for ALMOST all test cases. Except in the case where there is only ONE sub-element and that happens to be an asterisk.

For instance consider this in the input:

<MYROOT><Address3><Line2>*</Line2><Line3>*</Line3></Address3></MYROOT>

works well. It produces this output:

<MYROOT><Address3><Line2/><Line3/></Address3></MYROOT>

The xml input below, however , produces an incorrect response.

<MYROOT><Address4><PermanentAddress><Line2>*</Line2></PermanentAddress></Address4></MYROOT>

But instead of giving the response as

<MYROOT><Address4><PermanentAddress><Line2></Line2></PermanentAddress></Address4></MYROOT>

It gives this:

<MYROOT/>

Please help. Any help is appreciated as I did not have this test case while testing my code.


Solution

  • That's because . is the inner text, which is a concatenation of all inner text nodes. You need to make sure in your condition that there is no child node either or only a text node with * as contents.

    This should work:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="no"/>
    
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="*[not(*) and (. = '*')] | @*[. = '*']">
            <xsl:copy />
        </xsl:template>
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>