user1831774
user1831774

Reputation: 33

Java - how to filter XML document and create new XML with filtered data

I have following input file, what I want to do is to fiter on criteria like REDCode,Term And Name, I have attached sample input and sample output.

Input file

<?xml version="1.0"?>
<data>

    <row>
        <Date>2013-01-07</Date>
        <Name>CDXNAIG</Name>
        <Series>3</Series>
        <Version>1</Version>
        <Term>10Y</Term>
        <REDCode>2I65BYAB1</REDCode>
        <IndexID>DJCDX-NAIGS3V1-10Y</IndexID>
        <Maturity>2015-03-20</Maturity>
        <OnTheRun>N</OnTheRun>
        <ModelPrice>0.9949284642210332</ModelPrice>
        <ModelSpread>0.009331104270305838</ModelSpread>
    </row>
    <row>
        <Date>2013-01-07</Date>
        <Name>CDXNAIGCONS</Name>
        <Series>3</Series>
        <Version>1</Version>
        <Term>10Y</Term>
        <REDCode>2I65B0AB5</REDCode>
        <IndexID>DJCDX-NAIGCONSS3V1-10Y</IndexID>
        <Maturity>2015-03-20</Maturity>
        <OnTheRun>N</OnTheRun>
        <ModelPrice>0.9840941282706241</ModelPrice>
        <ModelSpread>0.014379157758592408</ModelSpread>
    </row>
    <row>
        <Date>2013-01-07</Date>
        <Name>CDXEMexEU</Name>
        <Series>18</Series>
        <Version>1</Version>
        <Term>5Y</Term>
        <REDCode>1D765JAA2</REDCode>
        <IndexID>CDX-EM-EXEUS18V1-5Y</IndexID>
        <Maturity>2017-12-20</Maturity>
        <OnTheRun>Y</OnTheRun>
        <CompositePrice>1.1397499612219184</CompositePrice>
        <CompositeSpread>0.019792819070343613</CompositeSpread>
        <ModelPrice>1.1359120550302715</ModelPrice>
        <ModelSpread>0.020550114606075833</ModelSpread>
        <Depth>8</Depth>
        <Heat>0.2778164733341895</Heat>
    </row>
    <row>
        <Date>2013-01-07</Date>
        <Name>CDXEMexEU</Name>
        <Series>18</Series>
        <Version>1</Version>
        <Term>10Y</Term>
        <REDCode>1D765JAA2</REDCode>
        <IndexID>CDX-EM-EXEUS18V1-10Y</IndexID>
        <Maturity>2022-12-20</Maturity>
        <OnTheRun>Y</OnTheRun>
        <CompositePrice>1.2256727099999931</CompositePrice>
        <CompositeSpread>0.022458778204998295</CompositeSpread>
        <ModelPrice>1.2203158240779826</ModelPrice>
        <ModelSpread>0.02301955731474385</ModelSpread>
        <Depth>3</Depth>
        <Heat>0.280354127626739</Heat>
    </row>
</data>

After Applying Filter REDCode=2I65BYAB1 OutPut should look like this

<row>
    <Date>2013-01-07</Date>
    <Name>CDXNAIG</Name>
    <Series>3</Series>
    <Version>1</Version>
    <Term>10Y</Term>
    <REDCode>2I65BYAB1</REDCode>
    <IndexID>DJCDX-NAIGS3V1-10Y</IndexID>
    <Maturity>2015-03-20</Maturity>
    <OnTheRun>N</OnTheRun>
    <ModelPrice>0.9949284642210332</ModelPrice>
    <ModelSpread>0.009331104270305838</ModelSpread>
</row>

Upvotes: 1

Views: 1771

Answers (1)

helderdarocha
helderdarocha

Reputation: 23627

To obtain the matching node or node-sets in XSLT you would have to run a template matching your criteria based on input (possibly a parameter value sent to the processor).

For example, suppose you run your XSLT Processor using Java, you could use something like:

Source xslt = new StreamSource(new FileInputStream("stylesheet.xsl"));
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(xslt);

Source input = new StreamSource(new FileInputStream("input.xml"));

public Result searchByRedCode(String redcode) { 
    Result result = new StreamResult(new FileOutputStream("result.xml"));
    t.setParameter("redcode", redcode); // this sends the parameter
    t.transform(input, result);
}

This will place your result in result.xml.

Now in your stylesheet, you should declare a global parameter:

<xsl:param name="redcode" />

Then you can use a XPath expression to retrieve all rows that match your code:

//row[REDCode = $redcode]

This stylesheet will do that:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:param name="redcode" />
    <xsl:template match="/">
        <xsl:apply-templates select="//row[REDCode = $redcode]" />
    </xsl:template>

    <xsl:template match="row">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>

If you want to add search criteria, you have to decide how to combine them (AND, OR) then you can also use parameters to send that information to XSLT and use more elaborated XPath expressions to select what you want.

Upvotes: 2

Related Questions