Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: как работает IXMLDOMNode?  (Прочитано 21413 раз)
0 Пользователей и 1 Гость смотрят эту тему.
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« : 24-07-2010 08:39 » 

допустим, имеем

Код:
  <node>value</node>

грузим в IXMLDOMNode. при этом имеем:

IXMLDOMNode.nodeName = node;
IXMLDOMNode.nodeValue = '';
IXMLDOMNode.nodeType = NODE_ELEMENT;

а вот если пробежаться по наследникам, то в одном из них, у которого nodeType = NODE_TEXT, IXMLDOMNode.nodeValue = value.

если забить на DOM-овскую модель и парсить обычным дельфийским TXMLDocument, то для такого нода имя = node, а значение - value, и нет никакой необходимости парсить детей нода, только чтобы узнать его значения. и это логично, в общем-то.

вопрос в следующем, что, IXMLDOMNode всегда хранит своё значение, как дочерний нод?

то ли я тупой, то ли лыжи не едут...

Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 24-07-2010 09:40 » 

Насколько я помню, да. Каждый вложенный элемент расматривается как отдельный. Т.е. значение value расматривается как отдельный элемент. Ну в принципе с точки зрения парсинга. Облегчили себе жизнь Улыбаюсь
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #2 : 24-07-2010 09:45 » 

если бы не селекты через XPath - выкинул бы всё это в топку :/

ладно, спасибо Улыбаюсь
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 24-07-2010 14:07 » 

x77, это для того, чтобы парсить выражения типа
Код:
<p>Абзац с <em>выделенным</em> текстом</p>
Получается дерево: P(TEXT, EM(TEXT), TEXT). В противном случае непонятно, как спозиционировать em в тексте. А так всё очевидно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 25-07-2010 10:46 » 

Игорь, если тебе это чем-нибудь поможет - вот пример кода на VB по разбору XML-RPC:
http://svn.shelek.su/public/XML-RPC/VB6-client/trunk/CXMLRPCRequest.cls

Код:
Private Function decodeData(ByRef node As MSXML2.IXMLDOMNode) As CAssocItem
    Dim i As Long
    Dim nodes As MSXML2.IXMLDOMNodeList
    Dim key As String
    Dim value As CAssocItem
    Dim itime As New CInetTime
    Dim b64 As New CBase64
    Dim tmpNode As MSXML2.IXMLDOMNode
    Dim text As String

    Set decodeData = New CAssocItem

    If node.nodeName = "array" Then
        Set nodes = node.selectNodes("data/value")
        Set decodeData.value = New Collection

        For i = 0 To nodes.length() - 1
            Set value = decodeData(nodes.item(i).firstChild)
            Call decodeData.value.Add(value.value)
        Next
    ElseIf node.nodeName = "struct" Then
        Set nodes = node.selectNodes("member")
        Set decodeData.value = New CAssocArray

        For i = 0 To nodes.length() - 1
            key = nodes.item(i).selectSingleNode("name/text()").nodeValue
            Set value = decodeData(nodes.item(i).selectSingleNode("value/*"))
            Call decodeData.value.Add(key, value.value)
        Next
    Else
        Set tmpNode = node.selectSingleNode("text()")

        If tmpNode Is Nothing Then
            text = ""
        Else
            text = tmpNode.nodeValue
        End If

        If node.nodeName = "boolean" Then
            decodeData.value = CBool(CLng(text))
        ElseIf node.nodeName = "int" Or node.nodeName = "i4" Then
            decodeData.value = CLng(text)
        ElseIf node.nodeName = "double" Then
            decodeData.value = CDbl(text)
        ElseIf node.nodeName = "dateTime.iso8601" Then
            decodeData.value = itime.InternetTimeToVbLocalTime(text)
        ElseIf node.nodeName = "base64" Then
            decodeData.value = b64.DecodeBase64(text)
        ElseIf node.nodeName = "string" Then
            decodeData.value = CStr(text)
        Else
            Call Err.Raise("Unknown type.", , -1)
        End If
    End If
End Function

Тут я с тем же сталкивался, что либо врезать в "node/text()", либо node.nodeValue. Не знаю. как для Delphi, а для VB лучше оказалось первое. Интерфейс мы используем, вроде как, один и тот же - MSXML2.IXMLDOMNodeList.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #5 : 26-07-2010 07:13 » 

x77, это для того, чтобы парсить выражения типа
Код:
<p>Абзац с <em>выделенным</em> текстом</p>
Получается дерево: P(TEXT, EM(TEXT), TEXT). В противном случае непонятно, как спозиционировать em в тексте. А так всё очевидно.

а что, XML поддерживает теги внутри значения нода? o.O
Записан

x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #6 : 26-07-2010 07:18 » 

Ром, у меня по неким признакам выдираются определённые куски из десятка xml-ей, склеиваются, и выводятся на экран. в принципе, пофигу, где там эти значения хранятся, просто я через "классическую" домовскую модель работал мало, и слегка удивился. дельфийские реализации ДОМа и Сакса более "интуитивно понятны", и соответствуют визуальной структуре документа. а когда парсишь ДОМ именно как дерево, у тебя оказываются childnod-ы там, где в документе их и близко нет.

з.ы. а код я уже родной написал, но всё равно спасибо Ага
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 26-07-2010 09:17 » 

Цитата: x77
а что, XML поддерживает теги внутри значения нода? o.O
Ну... исходя из того, что XHTML их поддерживает, а сам является корректным XML - почему бы и нет?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #8 : 26-07-2010 12:22 » 

Dimka, есть смутное подозрение, что таки нет. ну да ладно.

ещё один глупый вопрос. имеем всё тот же IXMLDOMNode. как его можно закомментарить?
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 26-07-2010 12:41 » 

ещё один глупый вопрос. имеем всё тот же IXMLDOMNode. как его можно закомментарить?

Что ты имеешь в виду?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #10 : 26-07-2010 12:44 » 

мне нужно закомментарить в конечном файле тот участок XML, который представляет данный IXMLDOMNode.
Записан

x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #11 : 07-08-2010 10:52 » 

в продолжение темы, может у кого будут идеи...

есть файл (ы). из него выдраны куски XML в виде IXMLDOMNodeList через SelectNodes. всё это потом неким образом отображается, редактируется и т.д. возникла задача писать изменения на диск. возникает вопрос: к чему можно привязаться у IXMLDOMNode? никакой фигни, типа Tag-ов у него, есс-но, нет. хранить где-то указатели на сами интерфейсы? хранить полный путь для каждого редактируемого элемента, а потом по этому пути находить нужный нод? но это сработает далеко не всегда (если ноды одинаковые, например).

если коротко, то как можно привязаться к IXMLDOMNodeList или к любому его чилдрену?
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 07-08-2010 14:41 » 

x77, писать на диск изменения в файле, из которого выдраны куски?

У IXMLDOMNodeList, конечно, ничего нет, кроме экземпляров IXMLDOMNode. А у IXMLDOMNode есть свойств xml - получение текста XML данного узла; свойство ownerDocument - ссылка на документ, у которого, в свою очередь, тоже есть свойство xml и метод save(fileName).

По поводу tag-ов, у IXMLDOMNode есть свойство nodeName - имя тэга...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #13 : 07-08-2010 14:56 » 

ситуёвина следующая.

1. есть набор xml-конфигов для разных сущностей, причём по одной сущности может быть несколько конфигурационных узлов.
2. для выбранной сущности из конфигов выдирается всё, что её касается через XPath.
3. получаем несколько наборов IXMLNodeList, каждый набор соответствует одному файлу, а ChildNodes этого набора - узлам из этого файла, относящимся к выбранной сущности.

задача:
1. вывести всё на экран в виде дерева, где рутовыми узлами являются файлы, и для каждого рута идёт ветка с настройками для выбранной сущности из этого файла (сделано)
2. обеспечить редактирование и сохранение конфигов обратно на диск (который день моск ломаю).

например, есть такой конфиг, где критерием "сущности" является аттрибут name='A':

Код:
..
<recordset name='A' param='1'>
  <record>1-1</record>
  <record>1-2</record>
  <record>1-3</record>
</recordset>
<recordset name='A' param='2'>
  <record>2-1</record>
  <record>2-2</record>
  <record>2-3</record>
</recordset>
..

после выборки через selectNodes ('bla-bla-bla') будем иметь вот эти самые два чайлда: <recordset name='A' param='1'> и <recordset name='A' param='2'>. допустим, пользователь в программе в некоем дереве изменил значения для второго чайлда: вместо <record>2-2</record> воткнул <record>2-100</record>. и вот тут я пока не могу представить, каким хреном можно найти это место в исходном ноде, чтобы заменить значение и сбросить всё на диск. причём, ладно, если он его просто изменил, а если он ещё одно удалил, а ещё 8 - добавил?

пока единственным выходом видится перезаписывать документ целиком, но слишком велик риск переписать "чужое". (_:_), в общем.

буду благодарен за любые идеи.
Записан

x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #14 : 07-08-2010 14:59 » 

з.ы. если по простому - xml-документ отображается в левом дереве. стоит задача обратной синхронизации левого дерева с исходным документом.
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 07-08-2010 16:37 » 

Ну... помоему обычный map заводится, где для узлов нового дерева указаны ссылки на узлы старых деревьев. А узлы в старых деревьях перезаписывать целиком. Либо же не целиком, а сделать такую обёртку, которая бы при изменении в новом дереве генерировала бы событие, по котором каждое элементарное изменение, сделанное пользователем, переносилось бы в старые деревья.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zubr
Гость
« Ответ #16 : 07-08-2010 20:33 » 

К примеру, пользователь работает с компонентом TreeView, тогда:
1. Загружаем нужный xml-файл в память
2. Из загруженного xml загружаем TreeView, где с каждым нодом TreeView связываем ноде xml: TTreeNode.Data := IXMLDOMNodeList.Item
3. При появлении события OnChange в TreeView, зная нод в котором произошло событие по его свойству Data вычисляем нужный нод в xml.
Записан
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #17 : 10-08-2010 05:35 » 

zubr, допустим, что каждый нод дерева будет ссылаться на соответствующий интерфейс xml. но при добавлении новой записи, всё равно придётся собирать заново как минимум весь родительский узел. а узлы ещё должны уметь и копироваться, например, взять настройку одной сущности и скопировать её целиком или частично для другой.

наверное, всё таки буду пересобирать xml целиком :/
за ответы - спасибо.
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines