0

私は xquery を使い始めたばかりで、現在、次のことが機能しない理由がわかりません。2 つの 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' ...

ただし、クエリにはデフォルトの名前空間がないように見えるため、名前テストの ValueIWant は ValueIWant タグと一致しません。

ns1 プレフィックスにバインドされているのは同じ URL であるため、XPath 式で ValueIWant のプレフィックスに ns1 を付けると問題が解決するでしょうか?

または、追加することもできます

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

あなたのクエリで。ただし、名前 (「QNames」) を比較する場合、名前空間とローカル名のみが重要であり、プレフィックスは無関係であるため、通常は ns1 プレフィックスを使用することもできます。

于 2012-08-23T10:28:20.687 に答える