sanjeevRm
sanjeevRm

Reputation: 1606

To select element with multiple Namespaces on an element with XSLT 1.0/2.0

I have input xml which has elements with multiple namespaces, I need to transform this input xml into another xml format. However I am not sure how to specifiy multiple namespaces in xpath to select the value of the element AVResult which has two namespaces "a" and "i"

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
    xmlns:u="http://docs.oasis-open.org/2004/01/ty.xsd">
    <s:Header>

    </s:Header>
    <s:Body>
        <AVResponse
            xmlns="http://info.com/Contracts">
            <AVResult
                xmlns:a="http://NamespaceOne.com"
                xmlns:i="http://NamespaceTwo.com">
                <Errors
                    xmlns="http://schemas.Messages" />
                <ErrorDetail>
                    <Code>1718</Code>
                    <Description>Con Types: Sum should equal 100%</Description>
                </ErrorDetail>
                <Status xmlns="http://schemas.BaseMessages">Success</Status>
                <a:NewID>275373</a:NewID>
                <a:Valn>
                    <a:Locs>
                        <a:Loc>
                            <a:Builds>
                                <a:Build>
                                    <a:Totals>
                                        <a:Rcv>11430888.8146038</a:Rcv>
                                    </a:Totals>
                                </a:Build>
                            </a:Builds>
                        </a:Loc>
                    </a:Locs>
                </a:Valn>
            </AVResult>
        </AVResponse>
    </s:Body>
</s:Envelope>

Here is my XSLT:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fo="http://service.fo.com/"
    xmlns:ns1="http://info.com/Contracts"

    xmlns:a="http://NamespaceOne.com"
    xmlns:ns3="http://schemas.BaseMessages"
    xmlns:i="http://NamespaceTwo.com"
    exclude-result-prefixes="ns1 a s">

    <xsl:output method="xml" />
    <xsl:strip-space elements="*" />

    <xsl:template match="/">
        <xsl:apply-templates select="*"/>
    </xsl:template>
    <xsl:template match="s:Header">

    </xsl:template>

    <xsl:template match="s:Body/ns1:AVResponse">

       <xsl:apply-templates select="@* | node()" />

  </xsl:template>

  <xsl:template match="a:AVResult">

        <Builds>
            <response-header>
                <fo:response-messages>

                    <xsl:if
                        test="//Status='Success'">
                        <fo:response-message>
                            <fo:response-type>Status</fo:response-type>
                            <fo:response-code></fo:response-code>
                            <fo:response-description>
                                <xsl:value-of select="//AVResponse/AVResult/Status" />
                            </fo:response-description>
                        </fo:response-message>
                    </xsl:if>
                    <xsl:if test="//AVResponse/AVResult/Status='Error'">
                        <fo:response-message>
                            <fo:response-type>Status</fo:response-type>
                            <fo:response-code></fo:response-code>
                            <fo:response-description>
                                <xsl:value-of
                                    select="//ns1:AVResponse/a:AVResult/ns3:Status" />
                            </fo:response-description>
                        </fo:response-message>
                        <xsl:for-each
                            select="//ns1:AVResponse/ns1:AVResult/ns3:Errors">
                            <fo:response-message>
                                <fo:response-type>
                                    <xsl:value-of
                                        select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail">
                                    </xsl:value-of>
                                </fo:response-type>
                                <fo:response-code>
                                    <xsl:value-of
                                        select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Code">
                                    </xsl:value-of>
                                </fo:response-code>
                                <fo:response-description>
                                    <xsl:value-of
                                        select="//ns1:AVResponse/ns1:AVResult/ns3:Errors/ns3:ErrorDetail/ns3:Description">
                                    </xsl:value-of>
                                </fo:response-description>
                            </fo:response-message>
                        </xsl:for-each>
                    </xsl:if>
                </fo:response-messages>
            </response-header>
            <!--<xsl:for-each select="//a:Locs/a:Loc"> -->
            <Build>
                <property>
                    <fo:itv-output>
                        <fo:estimated-construction-amt>
                            <fo:amount>
                                <xsl:value-of
                                    select="//ns1:AVResponse/ns1:AVResult/a:Locs/a:Loc/a:Builds/a:Build/a:Totals/a:Rcv">
                                </xsl:value-of>
                            </fo:amount>
                            <fo:currency>USD</fo:currency>
                        </fo:estimated-construction-amt>
                    </fo:itv-output>
                </property>
            </Build>
            <!-- </xsl:for-each> -->
        </Builds>

    </xsl:template>
</xsl:stylesheet>

Here, How to include two namespace to select AVResult ?

Upvotes: 1

Views: 696

Answers (1)

John Ernst
John Ernst

Reputation: 1235

AVResult actually has three namespaces. It also takes on the namespace for its parent node AVResponse (xmlns="http://info.com/Contracts"). But, since the namespace for AVResponse does not have a prefix, you have to create a reference to it with a prefix in your stylesheet tag, which you already created as ns1. So, any time you want to reference AVResponse or any of it's child or grandchild nodes you have to use the ns1 prefix. Also, you can't put ns1 in exclude-result-prefixes and exclude it.

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:fo="http://service.fo.com/"
xmlns:ns1="http://info.com/Contracts"

xmlns:a="http://NamespaceOne.com"
xmlns:ns3="http://schemas.BaseMessages"
xmlns:i="http://NamespaceTwo.com"
exclude-result-prefixes="ns3 a i s b">


<xsl:template match="ns1:AVResult">
    do stuff
</xsl:template>

Upvotes: 1

Related Questions