在具有XSLT 1.0 / 2.0的元素上选择具有多个命名空间的元素

时间:2017-04-06 12:27:03

标签: xml xslt xslt-1.0 xslt-2.0 xml-namespaces

我输入的xml包含多个名称空间的元素, 我需要将此输入xml转换为另一种xml格式。但是我不确定如何在xpath中指定多个名称空间来选择具有两个名称空间的元素AVResult的值" a"和"我"

<?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>

这是我的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>

这里,如何包含两个命名空间来选择AVResult?

1 个答案:

答案 0 :(得分:0)

AVResult实际上有三个名称空间。它还为其父节点AVResponse采用命名空间(xmlns =&#34; http://info.com/Contracts")。但是,由于AVResponse的命名空间没有前缀,因此您必须使用样式表标记中的前缀创建对它的引用,该标记已经创建为ns1。因此,只要您想要引用AVResponse或其任何子节点或孙子节点,您就必须使用ns1前缀。此外,您不能将ns1放在exclude-result-prefixes中并将其排除。

<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>