#xml #abap #dom-traversal
#xml #abap #dom-обход
Вопрос:
Я хочу пройти через все узлы if_ixml_document . какой наилучший способ сделать это?
Пожалуйста, найдите образец документа.
<text>
<id>
<guid auto="false">
432543254543
</guid>
</id>
<title>
<short_title italics="on">
<bold language = "german">
"Hello"
</bold>
</short_title>
</title> </text>
В этом документе мне нужно пройти через узлы <text>, <id>, <guid> , <title>, <short_title>, <bold>
и т.д.
Заранее спасибо
С уважением, Алекс
Ответ №1:
Первый шаг — проанализировать ваш XML следующим образом. Вы, конечно, можете загрузить XML из файла в строку, но это всего лишь пример:
data: lr_xml type ref to cl_xml_document.
data: lr_node type ref to if_ixml_node.
data: lv_xml type string.
lv_xml = '<text> <id> <guid auto="false"> 432543254543 </guid> </id> <title> <short_title italics="on"> <bold language = "german"> "Hello"</bold> </short_title> </title> </text>'.
create object lr_xml.
lr_xml->parse_string( lv_xml ).
lr_node = lr_xml->get_first_node( ).
Теперь у вас есть экземпляр IF_XML_NODE, который указывает на корень вашего XML-документа. Теперь вы можете использовать различные методы для обхода XML-дерева и получения из него значений, используя различные методы, такие как GET_CHILDREN, GET_ATTRIBUTES, GET_NAME и т. Д.
Это будет нормально для довольно небольших XML-документов, хотя для повышения эффективности, если вы ищете определенный набор узлов, вы можете использовать запрос XPATH.
Комментарии:
1. большое спасибо за ответ. Во-первых, я не ищу какой-либо конкретный набор узлов. Я пишу очень общий метод, например, изменение значения атрибута всех элементов при некотором условии. Из этого кода я обязательно получу корневой узел. но после этого, если я использую такие методы, как get_children , я получу только непосредственный дочерний элемент корневого узла. В примере документа я получу элементы <id> и <title>, но я не получу дочерний элемент внутри них. Я ищу метод, который может обход всех элементов в документе.
2. Правильно, это дает вам только непосредственные дочерние элементы. Что вам нужно сделать, это написать рекурсивную подпрограмму для обхода всего документа. Надеюсь, у меня скоро будет время привести вам пример.
Ответ №2:
Вы можете найти подробное руководство по XML на веб-сайте документации SAP (в случае, если ссылка не работает правильно, перейдите к Руководству разработчика NetWeaver по help.sap.com и найдите «xml library»).
Глава «iXML ABAP Objects Jumpstart» должна помочь вам быстро начать работу. В параграфе «Итерация по всему DOM-дереву» приведен следующий пример кода:
data: iterator type ref to if_ixml_node_iterator,
node type ref to if_ixml_node.
iterator = document->create_iterator( ).
node = iterator->get_next( ).
while not node is initial.
* do something with the node
...
node = iterator->get_next( ).
endwhile.
Ответ №3:
Я надеюсь, что следующий пример может прояснить ситуацию:
DATA: lcl_xml_doc TYPE REF TO cl_xml_document,
lf_node TYPE REF TO if_ixml_node,
lf_value TYPE string,
i_xml type string,
lf_name TYPE string,
i_xml = 'PUT your XML HERE'.
CREATE OBJECT lcl_xml_doc.
IF lcl_xml_doc IS BOUND.
IF lcl_xml_doc->parse_string( i_xml ) EQ 0.
lf_node = lcl_xml_doc->m_document.
IF lf_node IS NOT INITIAL.
lf_iterator = lf_node->create_iterator( ).
lf_node = lf_iterator->get_next( ).
WHILE NOT lf_node IS INITIAL.
lf_name = lf_node->get_name( ).
lf_value = lf_node->get_value( ).
IF lf_name = 'text'.
" do something for text
ENDIF.
ENDIF.
lf_node = lf_iterator->get_next( ).
ENDWHILE.
ENDIF.
Наслаждайтесь,
Александр.
Ответ №4:
Ручной обход xml подвержен ошибкам и усложняется в меняющихся средах. Возможно, вы захотите проверить, действительно ли вам нужен прямой обход кода.
С помощью преобразований (XSLT) вы можете преобразовать XML в структурированные типы ABAP. Поддерживается XPath.
Объявление, тестирование и отладка преобразований выполняются с помощью редактора преобразований, открываемого транзакцией STRANS
.
XSLT доступен как тип преобразования: преобразование ABAP XSLT
В вашем коде ABAP вы просто вызовете элемент language CALL TRANSFORMATION
, и после этого данные будут готовы к обработке в вашей целевой структуре: Оператор ABAP: ‘ПРЕОБРАЗОВАНИЕ ВЫЗОВА’
Ответ №5:
Вы можете использовать DocumentTraversal
интерфейс, который должен быть реализован любой библиотекой DOM (у Xerces он есть):
Document doc = ...;
NodeIterator i = ((DocumentTraversal) doc).createNodeIterator(doc,
NodeFilter.SHOW_ELEMENT, null, false);
Element e = null;
while ((e = (Element) i.nextNode()) != null) {
// do stuff with element
}
Комментарии:
1. Вопрос помечен как вопрос ABAP, поэтому я предполагаю, что он относится к языку ABAP. Может быть, @user871912 может просто подтвердить.
2. @mydoghasworms. Предоставлено. Как оказалось, ABAP поддерживает те же интерфейсы, хотя и с немного другим синтаксисом 🙂