Почему IXMLNode.IsTextElement не возвращает True для элементов CDATA? - PullRequest
3 голосов
/ 07 декабря 2011

Мы используем Delphi 2007 и поставщика oxmldom Open XML.

Файл ввода в нормальных ситуациях выглядит примерно так:

<root>
  <child>Some Text</child>
</root>

Теперь нам нужно обработать входной файл, который использует тип узла CDATA:

<root>
  <child><![CDATA[Some special Text]]></child>
</root>

Node.IsTextElement неожиданно возвращает False, но Node.Text все еще работает, как и ожидалось.

Я знаю, что IXMLNode.IsTextElement - это просто удобный метод, но я нахожу это поведение довольно странным.

В качестве обходного пути мы теперь используем этот пользовательский метод:

class function TXmlUtils.IsTextOrCDataElement(ANode: IXMLNode): Boolean;
begin
  Result := False;
  if ANode.ChildNodes.Count = 0 then begin
    if ANode.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end else
  if ANode.ChildNodes.Count = 1 then begin
    if ANode.ChildNodes.First.NodeType in [ntText, ntCData] then begin
      Result := True;
    end;
  end;
end;

У меня вопрос: почему IsTextElement не работает с CDATA узлами и есть ли более простое решение?

Ответы [ 3 ]

2 голосов
/ 08 декабря 2011

Это не возвращает истину для узлов Cdata, потому что это не так, как было написано. К сожалению, потребители XML-данных, как правило, не должны интересоваться тем, как текст представлен в сериализованных данных. Ваша альтернатива в порядке.

1 голос
/ 08 декабря 2011

Как писал Ритсаерт Хорнстра в комментарии, CDATA не является ТЕКСТовым узлом дерева DOM.Это узел CDATA.

Свойство Text - это нечто другое.Например, когда текущий узел является атрибутом, Text, вероятно, вернет значение этого атрибута.

Если вы хотите проверить, является ли текущий узел узлом CDATA или узлом TEXT, просто используйте оператор Delphi is.Есть также что-то вроде nodeType свойства, которое вы используете в любом случае: -)

0 голосов
/ 24 июля 2013

Если вы хотите проверить, является ли текущий узел узлом CDATA или узлом TEXT, просто используйте оператор Delphi is.Есть также что-то вроде nodeType свойства, которое вы используете в любом случае: -)

? XML CDATA read 
...