powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Доступ к XML-ноде по имени
9 сообщений из 9, страница 1 из 1
Доступ к XML-ноде по имени
    #39916703
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi All,

Delphi 10.3.3

Есть XML, который вернул web-сервис:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
<SOAP-ENV:Envelope xmlns:SOAP-ENV=" http://schemas.xmlsoap.org/soap/envelope/"  xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"  xmlns:s=" http://www.w3.org/2001/XMLSchema"> 
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>SOAP-ENV:Server</faultcode>
         <faultstring>ОШИБКА #5001: ::::Organization with systemId 653d35ac--aa is not found in DB!</faultstring>
         <detail/>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Мне надо прочитать значения Nod 'faultcode' и 'faultstring'

Загружаю этот xml в TXMLDocument

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
 XMLDocument1.Active := False;
 XMLDocument1.XML.Text := <мой xml>;
 XMLDocument1.Options := XMLDocument1.Options - [doNodeAutoCreate, doAutoSave];
 XMLDocument1.Active := True;

 iRootNode := XMLDocument1.DocumentElement;

 iFindNode := iRootNode.ChildNodes.FindNode('Body');

 if Assigned(iFindNode) then
   iFindNode := iFindNode.ChildNodes.FindNode('Fault');

 if Assigned(iFindNode) then begin
   ShowMessage(iFindNode.ChildNodes['faultcode'].Text);
   ShowMessage(iFindNode.ChildNodes['faultstring'].Text);
 end else
   ShowMessage('Неправильный xml');


При вызове кода обращения, например к ноде 'faultcode', получаю ошибку:
Node "faultcode" not found.

Если же заменить код обращения к нодам по имени на код по номеру
Код: pascal
1.
2.
  ShowMessage(iFindNode.ChildNodes[0].Text);
  ShowMessage(iFindNode.ChildNodes[1].Text);


то данные возвращаются без ошибок.

Вопрос: Что я делаю не так ?
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39916811
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо указать явный namespace.

ChildNodes использует FindNode, а тот в свою очередь, если не указан namespace использует DefaultNamespaceURI списка
У вас DefaultNamespaceURI это xmlns:SOAP-ENV=" http://schemas.xmlsoap.org/soap/envelope/" из предыдущей ноды
Но.. В xml узел faultcode без префикса и метод FindNode считает, что по неймспейсу они не совпадают и не ищет.

Поэтому, когда у вас у дочерних элементов не указан неймспейс, надо явно указывать отсутствие неймспейса, если он есть у предка...
Код: pascal
1.
2.
ShowMessage(iFindNode.ChildNodes.FindNode('faultcode', '').Text);
ShowMessage(iFindNode.ChildNodes.FindNode('faultstring', '').Text);
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39916829
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stalker4,

Проще использовать IXMLDOMDocument - там есть (почти)полноценный XPath
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39916845
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X-Cite
Поэтому, когда у вас у дочерних элементов не указан неймспейс, надо явно указывать отсутствие неймспейса, если он есть у предка...
Да, так работает, спасибо.

X-Cite
Надо указать явный namespace.
Где именно ? В коде FindNode, как Вы в своем ответе, или где то еще ?

zinpub
Проще использовать IXMLDOMDocument - там есть (почти)полноценный XPath
Если можно, то поподробнее про это. Где брать, как использовать.
Может есть какая то статья или примеры по его использованию ?
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39916858
AlexeyM123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
XPath
https://theroadtodelphi.com/category/xpath/

а еще лучше найти OXML который был open source, или его предшественника OmniXML
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39916863
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stalker4
zinpub
Проще использовать IXMLDOMDocument - там есть (почти)полноценный XPath
Если можно, то поподробнее про это. Где брать, как использовать.
Может есть какая то статья или примеры по его использованию ?


Книжечка...
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39917704
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X-Cite
Надо указать явный namespace.
А можно ли как то указать TXMLDocument, что бы он не учитывал в работе с XML элемент namespace, т.е. работал с XML так, как будто там у Nod нет namespace ?
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39917792
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в самой xml их не будет - можно.

Пространство имен - это же часть xml.
<Item> и <xxx:Item> это разные узлы.

Правда если задать вот так, я не знаю, будет одно и тоже или нет, по идее одно и тоже.. xmlns="aa" и xmlns:xxx="aa"
...
Рейтинг: 0 / 0
Доступ к XML-ноде по имени
    #39918036
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Правда если задать вот так, я не знаю, будет одно и тоже или нет, по идее одно и тоже.. xmlns="aa" и xmlns:xxx="aa"
Любой элемент имеет пространство имен.
Если не указан префикс пространства имен, то используется пространство имен по умолчанию
Пространство имен по умолчанию равно значению "атрибута" xmlns (без двоеточия) в текущем элементе или в ближайшем родителе
Если "атрибут" xmlns не имеет ни сам элемент ни один из его родителей, то считается, что пространство имен по умолчанию равно пустой строке.

Слово "атрибут" взято в кавычки, потому, что декларации xmlns="..", xmlns:xxx="..." не попадают в стандартные коллекции атрибутов элемента
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Доступ к XML-ноде по имени
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]