Morten Frank
Morten Frank

Reputation: 269

Removing elements from an XML document, XSLT and JAXB

This question is a follow up to my earlier question: Creating a valid XSD that is open using <all> and <any> elements

Given that I have a Java String containing an XML document of the following form:

<TRADE>
  <TIME>12:12</TIME>
  <MJELLO>12345</MJELLO>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
  <HELLO>hello should be ignored</HELLO>
</TRADE>

How can I use XSLT or similar (in Java by using JAXB) to remove all elements not contained in a set of elements. In the above example I am only interested in (TIME, OPTIONAL, DATE), so I would like to transform it into:

<TRADE>
  <TIME>12:12</TIME>
  <OPTIONAL>12:12</OPTIONAL>
  <DATE>25-10-2011</DATE>
</TRADE>

The order of the elements is not fixed.

Upvotes: 4

Views: 2415

Answers (3)

bdoughan
bdoughan

Reputation: 148977

JAXB & XSLT

JAXB integrates very cleanly with XSLT for an example see:

Your Other Question

Based on your previous question (see link below), the transform is really unnecessary as JAXB will just ignore attributes and elements that are not mapped to fields/properties in your domain object.

Upvotes: 1

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

This transformation:

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

 <xsl:param name="pNames" select="'|TIME|OPTIONAL|DATE|'"/>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="*/*">
  <xsl:if test="contains($pNames, concat('|', name(), '|'))">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<TRADE>
    <TIME>12:12</TIME>
    <MJELLO>12345</MJELLO>
    <OPTIONAL>12:12</OPTIONAL>
    <DATE>25-10-2011</DATE>
    <HELLO>hello should be ignored</HELLO>
</TRADE>

produces the wanted, correct result:

<TRADE>
   <TIME>12:12</TIME>
   <OPTIONAL>12:12</OPTIONAL>
   <DATE>25-10-2011</DATE>
</TRADE>

Explanation:

  1. The identity rule (template) copies every node "as-is".

  2. The identity rule is overridden by a template matching any element that is not the top element of the document. Inside the template a check is made if the name of the matched element is one of the names specified in the external parameter $pNames in a pipe-delimited string of wanted names.

  3. See the documentation of your XSLT processor on how to pass a parameter to a transformation -- this is implementation-dependent and differs from processor to processor.

Upvotes: 6

Puce
Puce

Reputation: 38122

I haven't tried yet, but maybe the javax.xml.tranform package can help:

http://download.oracle.com/javase/6/docs/api/javax/xml/transform/package-summary.html

Upvotes: 1

Related Questions