Delphi - неверный URI пространства имен в IXMLNode - PullRequest
1 голос
/ 06 мая 2009

Я пытаюсь проанализировать ответ от веб-службы SOAP, но часть данных содержит недопустимый элемент 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>

URI xmlns в узле soap: Body в норме, недопустимый в ResponseData, он указывает на несуществующий документ. Следует отметить, что веб-сервис не находится под моим контролем, поэтому об этом не может быть и речи: (.

мой код 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. Я могу посмотреть на xml с помощью l_tmp.xml и увидеть, что это XML, который я ожидаю.

Я подозреваю, что это связано с отсутствием пространства имен, поэтому я попытался удалить его, но получаю больше ошибок, говоря, что это атрибут только для чтения.

Есть ли в любом случае удалить атрибут xmlns или выбрать узлы независимо от того, есть ли NS? или я ошибаюсь?

1 Ответ

2 голосов
/ 06 мая 2009

не ожидается , что все URI пространства имен ссылаются на фактические ресурсы. Они используются в основном как уникальные идентификаторы, поэтому XML из нескольких источников может использовать одни и те же имена, не мешая друг другу. Они не обязаны указывать на схему, которая описывает допустимые значения элемента и атрибута для пространства имен; XML даже не требует, чтобы такая схема существовала.

Если вы хотите искать элементы без учета пространства имен, то вызовите версию с одним аргументом FindNode.

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

Версия с двумя аргументами требует пространства имен, а когда вы указываете пустую строку, это означает, что вы запрашиваете только узлы, которые имеют пустые пространства имен. Поскольку вы, очевидно, знаете, что такое пространство имен, вы можете в любом случае вызвать версию с двумя аргументами, точно так же, как вы использовали ее для получения элемента body:

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