0

我只是从 xquery 开始,目前我不知道,为什么以下不起作用。我创建了两个 XML 文件,它们是相同的,除了一个有命名空间而另一个没有:

<Envelope>
    <Header>
        <JustAValue>12345</JustAValue>
    </Header>
    <Body>
        <someBody>
            <ValueIWant>12345678910</ValueIWant>
        </someBody>
    </Body>
</Envelope>


<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
    <env:Header xmlns:wsa='http://www.w3.org/2005/08/addressing'>
        <JustAValue>12345</JustAValue>
    </env:Header>
    <env:Body xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' wsu:Id='element-28-1344266615792-223644235'>
        <ns1:someBody xmlns='http://someURL.com' xmlns:ns1='http://someURL.com'>
            <ValueIWant>12345678910</ValueIWant>
        </ns1:someBody>
    </env:Body>
</env:Envelope>

两个 xml 文件都位于数据库的 xml 字段中。

现在我尝试获得“ValueIWant”,我这样做:

DECLARE @xml xml

Select @xml = completexml from MyDB.dbo.Xml where PKxml = 3 -- XML without namespaces

declare @somevalue nvarchar(max)

set @somevalue = @xml.value('(/Envelope/Body/someBody/ValueIWant/text())[1]', 'nvarchar(max)');

select @somevalue -- -> 12345678910


Select @xml = completexml from MyDB.dbo.Xml where PKxml = 2 -- XML with namespaces

set @somevalue = @xml.value('
declare namespace env="http://schemas.xmlsoap.org/soap/envelope/"; 
declare namespace ns1="http://someURL.com"; 
(/env:Envelope/env:Body/ns1:someBody/ValueIWant/text())[1]', 'nvarchar(max)');

select @somevalue -- -> NULL

我在这里做错了什么?

我玩过一些 XML:

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
    <env:Header xmlns:wsa='http://www.w3.org/2005/08/addressing'>
        <JustAValue>12345</JustAValue>
    </env:Header>
    <env:Body xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' wsu:Id='element-28-1344266615792-223644235'>
        <ns1:someBody xmlns='http://someURL.com' xmlns:ns1='http://someURL.com'>
            <ValueIWant>12345678910</ValueIWant>
        </ns1:someBody>
        <BodyValue>BodyValue</BodyValue>
        <env:BodyValue>BodyValue</env:BodyValue>
    </env:Body>
    <env:TestValue1>TestValue</env:TestValue1>
    <TestValue2>TestValue2</TestValue2>
</env:Envelope>

我可以获得所有值:BodyValue、TestValue1 和 TestValue2。完全没问题,但只要我想更改为 ns1 命名空间并获取 ValueIWant,它就会返回 NULL。

4

1 回答 1

1

ValueIWant 元素标记名称位于默认命名空间 (http://someURL.com) 中,因为此命名空间由其父元素绑定到空前缀:

<ns1:someBody xmlns='http://someURL.com' ...

但是在查询中似乎没有默认命名空间,因此名称 test ValueIWant 与 ValueIWant 标记不匹配。

由于它是绑定到 ns1 前缀的同一个 URL,也许在 XPath 表达式中使用 ns1 作为 ValueIWant 前缀可以解决问题?

或者,您可以添加一个

declare default element namespace "http://someURL.com";

在您的查询中。但是使用 ns1 前缀通常也可以工作,因为在比较名称(“QNames”)时,只有名称空间和本地名称很重要,前缀无关紧要。

于 2012-08-23T10:28:20.687 回答