bilak
bilak

Reputation: 4922

XSLT copy elements with condition

at first I would like to know if this is even possible using xslt and if so how to do that:

I have two xmls. The first one is holding informations about invoices

<INVOICES>
    <INVOICE>
        <INVOICE_NUMBER>FV2014000572</INVOICE_NUMBER>
        <SUPPLIER_NAME>Supplier 1</SUPPLIER_NAME>
    </INVOICE>
    <INVOICE>
        <INVOICE_NUMBER>FV2014000573</INVOICE_NUMBER>
        <SUPPLIER_NAME>Supplier 1</SUPPLIER_NAME>
    </INVOICE>
</INVOICES>

and second is holding concrete informations about invoice items

<INVOICE_ITEMS>
    <INVOICE_ITEM>
        <ITEM_INVOICE_NUMBER>FV2014000572</ITEM_INVOICE_NUMBER>
        <ITEM_NAME>ITEM 1</ITEM_NAME>
    </INVOICE_ITEM>
    <INVOICE_ITEM>
        <ITEM_INVOICE_NUMBER>FV2014000573</ITEM_INVOICE_NUMBER>
        <ITEM_NAME>ITEM 1</ITEM_NAME>
    </INVOICE_ITEM>
    <INVOICE_ITEM>
        <ITEM_INVOICE_NUMBER>FV2014000573</ITEM_INVOICE_NUMBER>
        <ITEM_NAME>ITEM 2</ITEM_NAME>
    </INVOICE_ITEM>
<INVOICE_ITEMS>

I'd like to transform this two xmls to one in following format:

<INVOICES>
    <INVOICE>
        <INVOICE_NUMBER>FV2014000572</INVOICE_NUMBER>
        <SUPPLIER_NAME>Supplier 1</SUPPLIER_NAME>
        <INVOICE_ITEMS>
            <INVOICE_ITEM>
                <ITEM_INVOICE_NUMBER>FV2014000572</ITEM_INVOICE_NUMBER>
                <ITEM_NAME>ITEM 1</ITEM_NAME>
            </INVOICE_ITEM>
        </INVOICE_ITEMS>
    </INVOICE>
    <INVOICE>
        <INVOICE_NUMBER>FV2014000573</INVOICE_NUMBER>
        <SUPPLIER_NAME>Supplier 1</SUPPLIER_NAME>
        <INVOICE_ITEMS>
            <INVOICE_ITEM>
                <ITEM_INVOICE_NUMBER>FV2014000573</ITEM_INVOICE_NUMBER>
                <ITEM_NAME>ITEM 1</ITEM_NAME>
            </INVOICE_ITEM>
            <INVOICE_ITEM>
                <ITEM_INVOICE_NUMBER>FV2014000573</ITEM_INVOICE_NUMBER>
                <ITEM_NAME>ITEM 2</ITEM_NAME>
            </INVOICE_ITEM>
        </INVOICE_ITEMS>
    </INVOICE>
</INVOICES>

And if possible remove ITEM_INVOICE_NUMBER element from final xml.

Thanks

Upvotes: 1

Views: 1067

Answers (1)

potame
potame

Reputation: 7905

This very basic stylesheet should give you a clue on how to proceed. It will be applied to the first XML you provided us in input, and it assumes that the second XML storing additional information is named data.xml.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:variable name="invoiceitems" select="document('data.xml')" />

    <!-- just copy the element, and process contents. Warning: attributes (if any) won't be processed. -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="INVOICE">
        <xsl:variable name="current.invoice.number" select="INVOICE_NUMBER" />
        <xsl:copy>
            <xsl:apply-templates />
            <!-- create an INVOICE_ITEMS element, and start to retrieve information from the other XML -->
            <INVOICE_ITEMS>
                <xsl:apply-templates select="$invoiceitems//INVOICE_ITEM[ITEM_INVOICE_NUMBER/text() = $current.invoice.number]"></xsl:apply-templates>
            </INVOICE_ITEMS>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions