添加命名空间时,XSLT未选择某些元素

时间:2015-12-24 00:59:45

标签: xml xslt

当我将命名空间添加到文档的标题中时,某些元素的XPath表达式失败。 stackOverflow上其他地方的解决方案建议将命名空间添加到元素中。但是,我已经在XPath中拥有名称空间。失败的元素在两个方面有所不同。 1)它们有多个XPath条目,2)它们在元素层次结构中有一个额外的级别。

源文件是(我为了简洁而编辑):

<ns0:SubscriptionNotification xmlns:ns1="urn:base.ws.rightnow.com/v1_3" xmlns:ns2="urn:objects.ws.rightnow.com/v1_3" xmlns:ns0="http://xmlns.oracle.com/cloud/adapter/rightnow/StudentJSEndpoint_REQUEST/types">
    <ns0:Organization>
       <ns2:Addresses>
         <ns2:TypedAddressList action="action16">
            <ns2:City>City13</ns2:City> <!-- Xpath works -->
            <ns2:Country>
               <ns1:ID id="id18"/>
               <ns1:Name>Name17</ns1:Name>
            </ns2:Country> <!-- Xpath does not work -->
            <ns2:Country xsi:type="NamedReadOnlyID" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
               <ns1:ID id="id20"/>
               <ns1:Name>Name19</ns1:Name>
            </ns2:Country>

         </ns2:TypedAddressList> 
      </ns2:Addresses>
      <ns2:Name>Name8</ns2:Name>

   </ns0:Organization>
</ns0:SubscriptionNotification>

具有命名空间标头但未找到Country属性的XSL是:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:base.ws.rightnow.com/v1_3" xmlns:ns2="urn:objects.ws.rightnow.com/v1_3" xmlns:ns0="http://xmlns.oracle.com/cloud/adapter/rightnow/StudentJSEndpoint_REQUEST/types">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">

    <nstrgmpr:createAccount xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:nsmpr1="http://xmlns.oracle.com/apps/crmCommon/salesParties/commonService/" xmlns:nstrgmpr="http://xmlns.oracle.com/cloud/adapter/osc/StudentBBEndpoint_REQUEST/types" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:errors="http://xmlns.oracle.com/adf/svc/errors/" xmlns:types="http://xmlns.oracle.com/apps/crmCommon/salesParties/accountService/types/" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:ns1="http://xmlns.oracle.com/cloud/adapter/osc/StudentBBEndpoint_REQUEST" xmlns:orafault="http://xmlns.oracle.com/oracleas/schema/oracle-fault-11_0" xmlns:tns="http://xmlns.oracle.com/apps/crmCommon/salesParties/accountService/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
        <nstrgmpr:account>
            <tns:OrganizationName>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Name"/>
            </tns:OrganizationName>
            <tns:PrimaryAddress>
                <nsmpr1:AddressLine1>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Street"/>
                </nsmpr1:AddressLine1>
                <nsmpr1:City>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:City"/>
                </nsmpr1:City>
                <nsmpr1:Country>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Country/ns1:Name"/>
                </nsmpr1:Country>
                <nsmpr1:PostalCode>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:PostalCode"/>
                </nsmpr1:PostalCode>
                <nsmpr1:State>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:StateOrProvince/ns1:Name"/>
                </nsmpr1:State>
            </tns:PrimaryAddress>
        </nstrgmpr:account>
    </nstrgmpr:createAccount>
</xsl:template>

使用不包含标题的XLS:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:base.ws.rightnow.com/v1_3" xmlns:ns2="urn:objects.ws.rightnow.com/v1_3" xmlns:ns0="http://xmlns.oracle.com/cloud/adapter/rightnow/StudentJSEndpoint_REQUEST/types">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
    <createAccount>
        <account>
            <OrganizationName><xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Name"/></OrganizationName>
            <PrimaryAddress>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Street"/>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:City"/>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Country/ns1:Name"/>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:PostalCode"/>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:StateOrProvince/ns1:Name"/>
            </PrimaryAddress>
        </account>
    </createAccount>
</xsl:template>

必须有一些在属性之间以不同方式处理XPath的东西,但我不太了解XSLT以确定问题。 createAccount中的ns似乎导致了问题。如果我删除它,转换工作。但我需要它作为输出的一部分,所以我不知道如何删除它。

1 个答案:

答案 0 :(得分:1)

这里的问题是你有两个冲突的命名空间声明将ns1前缀绑定到两个不同的URI。

在您声明的xsl:stylesheet元素中:

xmlns:ns1="urn:base.ws.rightnow.com/v1_3" 

然后在nstrgmpr:createAccount中通过声明:

来覆盖它
xmlns:ns1="http://xmlns.oracle.com/cloud/adapter/osc/StudentBBEndpoint_REQUEST"

当您在XPath表达式中使用ns1前缀选择Country时,后者声明属于范围 - 因此没有选择任何内容。

解决方案是在第一个声明中使用不同的前缀 - 例如:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns9="urn:base.ws.rightnow.com/v1_3" 
xmlns:ns2="urn:objects.ws.rightnow.com/v1_3" xmlns:ns0="http://xmlns.oracle.com/cloud/adapter/rightnow/StudentJSEndpoint_REQUEST/types">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <nstrgmpr:createAccount xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:nsmpr1="http://xmlns.oracle.com/apps/crmCommon/salesParties/commonService/" xmlns:nstrgmpr="http://xmlns.oracle.com/cloud/adapter/osc/StudentBBEndpoint_REQUEST/types" xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:errors="http://xmlns.oracle.com/adf/svc/errors/" xmlns:types="http://xmlns.oracle.com/apps/crmCommon/salesParties/accountService/types/" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:ns1="http://xmlns.oracle.com/cloud/adapter/osc/StudentBBEndpoint_REQUEST" xmlns:orafault="http://xmlns.oracle.com/oracleas/schema/oracle-fault-11_0" xmlns:tns="http://xmlns.oracle.com/apps/crmCommon/salesParties/accountService/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
        <nstrgmpr:account>
            <tns:OrganizationName>
                <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Name"/>
            </tns:OrganizationName>
            <tns:PrimaryAddress>
                <nsmpr1:AddressLine1>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Street"/>
                </nsmpr1:AddressLine1>
                <nsmpr1:City>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:City"/>
                </nsmpr1:City>

                <nsmpr1:Country>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:Country/ns9:Name"/>
                </nsmpr1:Country>

                <nsmpr1:PostalCode>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:PostalCode"/>
                </nsmpr1:PostalCode>
                <nsmpr1:State>
                    <xsl:value-of select="ns0:SubscriptionNotification/ns0:Organization/ns2:Addresses/ns2:TypedAddressList/ns2:StateOrProvince/ns1:Name"/>
                </nsmpr1:State>
            </tns:PrimaryAddress>
        </nstrgmpr:account>
    </nstrgmpr:createAccount>
</xsl:template>

</xsl:stylesheet>

另请注意,输入有两个Country个节点 - 但在XSLT 1.0中,xsl:value-of指令只返回所选节点集中第一个节点的值。