rwolters3
rwolters3

Reputation: 73

XSLT-XPath: Check if value exists in list

I've seen a few examples of different ways to check if a value (node) exist in a list (recurring XML variable), but for some reason I can't figure out the exact syntax of the Xpath statement I need to be using. I have one XML document that is a list of invoice lines, and another XML document that is a list of incorrect lines. If a value in the first document exists in the second, I need to put/replace it with a value of "X", otherwise leave blank.

Here is a sample input document

Input1

<?xml version="1.0" encoding="UTF-8"?>
<UPSOutboundFlatFileSchema>
    <data>
        <processFlag>1</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag>2</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag>3</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag>4</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
</UPSOutboundFlatFileSchema>

Input2

<?xml version="1.0" encoding="UTF-8"?>
<rows>
    <row>
        <LineNumber>2</LineNumber>
    </row>
    <row>
        <LineNumber>3</LineNumber>
    </row>
</rows>

Output Document

<?xml version="1.0" encoding="UTF-8"?>
<UPSOutboundFlatFileSchema>
    <data>
        <processFlag></processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag>X</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag>X</processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
    <data>
        <processFlag></processFlag>
        <field1>...</field1>
        <field2>...</field2>
    </data>
</UPSOutboundFlatFileSchema>

Here's the XSLT I have so far, I just can't get the XPath statement on the first "when test = " correct...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output indent="yes"/>
    <xsl:variable name="rejectLines" select="bpws:getVariableData('UPSDataRejectLineNumbers')"/>
    <xsl:variable name="input" select="/"/>

    <xsl:template match="/">

        <xsl:element name="UPSOutboundFlatFileSchema">    
            <xsl:for-each select="$input/*:UPSOutboundFlatFileSchema/*:data">
                <xsl:element name="data">
                    <xsl:choose>
                        <xsl:when test="boolean($rejectLines/*:rows/*:row/*:LineNumber = processFlag">
                            <xsl:element name="processFlag">
                                <xsl:value-of select="X"/>
                            </xsl:element>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:element name="processFlag">
                                <xsl:value-of select="''"/>
                            </xsl:element>                
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:copy-of select="child::*[not(self::processFlag)]"/>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>    
    </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Views: 6032

Answers (1)

G. Ken Holman
G. Ken Holman

Reputation: 4403

Don't kick yourself too hard, but where you have <xsl:value-of select="X"/> you need <xsl:text>X</xsl:text>. There is no element named X in your input data.

And while you are at it, for your otherwise you just need <xsl:element name="processFlag"/>.

There is no need for <xsl:value-of/> if all you have is a single string argument.

Upvotes: 3

Related Questions