由于嵌套XML标记中的“单独”xmlns属性导致XML上的XSL转换问题

时间:2016-06-02 21:08:33

标签: xml xslt soap xml-namespaces

尝试第一次

我有一个页面正在通过SOAP从Web服务检索响应。我试图将XSL转换应用于响应,但是,我遇到了一个问题,因为嵌套标记包含唯一的'xmlns'属性。

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <GetPartA xmlns="http://obfuscated.url.com/">
            <GetPartB>
                <Status>Ok</Status>
            </GetPartB>
        </GetPartA >
    </soap:Body>
</soap:Envelope>

根据我在网上收集的内容,该解决方案涉及在xsl文件中声明命名空间,并使用此命名空间来精确选择,因为包含xmlns标记的元素与不包含xmlns标记的元素不同。这很好,但它仍然没有用。

<xsl:stylesheet 
    xmlns:np="http://obfuscated.url.com/"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:template match="/">
        <xsl:value-of select="soap:Envelope/soap:Body/np:GetPartA/GetPartB/Status"/>    
    </xsl:template>
</xsl:stylesheet>

调试信息

以下组合可以更精确地查明问题。

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <GetPartA>
            <GetPartB>
                <Status>Ok</Status>
            </GetPartB>
        </GetPartA >
    </soap:Body>
</soap:Envelope>

请注意,&lt; GetPartA&gt;已从&lt; GetPartA xmlns =“http://obfuscated.url.com/”&gt;修改。

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:template match="/">
        <xsl:value-of select="soap:Envelope/soap:Body/GetPartA/GetPartB/Status"/>    
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:3)

当你这样做时......

 <GetPartA xmlns="http://obfuscated.url.com/">

然后,这将声明一个默认命名空间,因此GetPartA及其所有后代都在此命名空间中。对于名称空间,使用的前缀(或在这种情况下缺少前缀)不是关键因素,它是命名空间uri(在这种情况下为&#34; http://obfuscated.url.com/&#34;),需要匹配XML和XSLT。使用的前缀可能不同。

你的第一次尝试实际上并不遥远。您只需在XPath表达式中使用npGetPartB之前的Status

试试这个XSLT:

<xsl:stylesheet 
    xmlns:np="http://obfuscated.url.com/"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:template match="/">
        <xsl:value-of select="soap:Envelope/soap:Body/np:GetPartA/np:GetPartB/np:Status"/>    
    </xsl:template>
</xsl:stylesheet>