Delphi-IXMLNodeの名前空間URIが無効です
-
06-07-2019 - |
質問
SOAP Webサービスからの応答を解析しようとしていますが、データの一部に無効なxmlns要素が含まれているため、問題が終わらないと思われます。
XMLで作業している部分は次のとおりです。
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ResponseData xmlns="http://www.example.com/WebServices/Schemas/1">
<ResponseDataResult>
<Messages xmlns="http://www.example.com/WebServices/Schemas/2">
<Message>...</Message>
</Messages>
</ResponseDataResult>
...
</ResponseData>
</soap:Body>
soap:Bodyノードのxmlns URIはOKであり、ResponseDataの無効なURIは存在しないドキュメントを指します。 Webサービスは私の制御下にないため、これを修正することは問題外です:(。
現在、私のDelphi(2007)コードは、このようなものです。
var l_tmp,l_tmp2,FSOAPBody:IXMLNode;
begin
...
FSOAPBody := FSOAPEnvelope.ChildNodes.FindNode('Body','http://schemas.xmlsoap.org/soap/envelope/');
//returns the xml above.
if (FSOAPBody = nil) then exit;
l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData','');
if (l_tmp = nil) or (not l_tmp.HasChildNodes) then exit;
l_tmp2 := l_tmp.ChildNodes.FindNode('ResponseDataResult','');
...
end;
上記のコードでは、空の名前空間urlを FindNode( 'ResponseData'、 '')
コードに追加する必要がありました。これは何も検出せず、nilを返すためです。ただし、期待されるXMLを再度取得します。
問題は、次の検索ノード( ChildNodes.FindNode( 'ResponseDataResult'、 '')
)がl_tmpのChildNodesにアクセスしようとするとアクセス違反を発生させることです。xmlを見ることができますl_tmp.xmlを使用して、それが私が期待するXMLであることを確認します。
名前空間が欠落しているためと思われるため、削除しようとしましたが、読み取り専用属性であるというエラーがさらに表示されます。
とにかくxmlns属性を削除したり、NSに関係なくノードを選択したりできますか?または私はこれについて間違っていますか?
解決
すべての名前空間URIが実際のリソースを参照することは予想外です。これらは主に一意の識別子として使用されるため、複数のソースからのXMLは、互いに干渉することなく同じ名前を使用できます。名前空間の有効な要素と属性値を記述するスキーマを指す必要はありません。 XMLは、そのようなスキーマが存在することさえ要求しません。
名前空間に関係なく要素を検索する場合は、引数が1つのバージョンの FindNode
を呼び出します。
l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData');
2引数バージョンには名前空間が必要です。空の文字列を指定すると、空の名前空間を持つノードのみをリクエストすることになります。名前空間が明らかにわかっているので、body要素を取得するために使用したように、とにかく2引数バージョンを呼び出すことができます。
l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData',
'http://www.example.com/WebServices/Schemas/1');