Delphi - IXMLNode中的名称空间URI无效

时间:2009-05-06 08:48:11

标签: xml delphi namespaces xml-namespaces

我正在尝试解析来自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中是无效的,它指向一个不存在的文档。应该注意的是,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时引发访问冲突,我可以使用l_tmp.xml查看xml,看看它是XML我会期望的。

我怀疑它是由于缺少命名空间,所以我试图删除它,但是得到更多错误,说它是一个只读属性。

无论如何都要移除xmlns属性或选择节点而不管NS是什么?或者我错了?

1 个答案:

答案 0 :(得分:2)

不期望所有名称空间URI都引用实际资源。它们主要用作唯一标识符,因此来自多个源的XML可以使用相同的名称而不会相互干扰。它们不需要指向描述命名空间的有效元素和属性值的模式; XML甚至不需要存在这样的模式。

如果要在不考虑名称空间的情况下搜索元素,请调用FindNode的单参数版本。

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData');

双参数版本需要命名空间,当您指定空字符串时,这意味着您只请求具有空命名空间的节点。既然您显然知道命名空间是什么,那么无论如何都可以调用双参数版本,就像您使用它来获取body元素一样:

l_tmp := FSOAPBody.ChildNodes.FindNode('ResponseData',
           'http://www.example.com/WebServices/Schemas/1');