[Решено] Xml (из .odt) - как получить текст вместе с tab'ими

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

[Решено] Xml (из .odt) - как получить текст вместе с tab'ими

Сообщение qqqq1 » 14.05.2011 17:55:01

Есть xml файл (content.xml) из odt файла. Из него надо получить текст. Проблема состоит в том, что tab и перевод строки находятся внутри узла с текстом. Например:
Код: Выделить всё
<text:p text:style-name="Standard">
  <text:span text:style-name="T2">
   Код
   <text:tab />
   вопроса 1: 
   <text:line-break />
   Текст ...
  </text:span>
</text:p>

Нахожу узел (text:span) получаю из него текст (Node.TextContent), однако узлы text:tab и text:line-break не обрабатываются (точнее обрабатываются, но позже - когда перехожу к следующему узлу).
Сейчас приходится вначале заменять <text:tab /> и <text:line-break /> на что-то уникальное, а только потом вытаскивать текст из файла. После этого в полученном тексте снова заменяю нечто уникальное на #9 и #13#10 соответсвенно.
Как-то некрасиво получается. Может можно получить текст как-то по-другому?
Последний раз редактировалось qqqq1 15.05.2011 17:08:16, всего редактировалось 1 раз.
qqqq1
новенький
 
Сообщения: 12
Зарегистрирован: 20.08.2010 13:01:46

Re: Xml (из .odt файла) - как получить текст вместе с tab'ими

Сообщение Odyssey » 15.05.2011 14:17:42

По хорошему, нужно пройтись по дочерним узлам text:span'а и склеить текст в зависимости от типа и значения узлов. У text:span будут три дочерних текстовых узла (Node is TDOMText, Node.NodeType = TEXT_NODE) - "Код", "вопроса 1:" и "Текст...", между которыми вставлены элементы (Node is TDomElement, Node.NodeType = ELEMENT_NODE) - text:tab и text:line-break. От текстовых узлов нужно взять текст, а от элементов, в зависимости от имени (Node.NodeName или (Node as TDomElement).TagName) - таб или перевод строки.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Xml (из .odt файла) - как получить текст вместе с tab'ими

Сообщение qqqq1 » 15.05.2011 17:05:01

Спасибо! Всё заработало.

Может кому пригодится

Код: Выделить всё
Function Odt2Txt(XMLDoc: TXMLDocument):string;
var
  iNode, iNode_s: TDOMNode; kol_0:integer;
  s: string; flg_1:boolean;
  procedure ProcessNode(Node: TDOMNode; var Node_s: TDOMNode; var kol_:integer; var flg_0:boolean);
  var
    cNode, cNode_tmp: TDOMNode; flg:boolean;
  begin
    if Node = nil then Exit; // выходим, если достигнут конец документа

    if Node.NodeName='table:table' then begin
       Node_s:=Node.NextSibling;
       flg_0:=true; // табица началась
    end;
    //строка таблицы
    if Node.NodeName='table:table-row' then begin
       s:=s+#13#10;
       kol_:=0;
    end;
    //ячейка таблицы
    if Node.NodeName='table:table-cell' then begin
      kol_:=kol_+1;
      if kol_>1 then s:=s+#9; //начальный таб не нужен, т.к. табами разделяем столбцы
    end;

    flg:=true;
    if flg_0 then
      if (Node<>Node_s) then flg:=false //пока не найдёт следующий за таблицей узел
      else flg_0:=false;

    if flg then begin  //игнорируем для таблицы
      //нашли параграф
      if (Node.NodeName='text:p') or (Node.NodeName='text:h') or (Node.NodeName='text:line-break')then
         if Node is TDomElement then s:=s+#13#10
    end;

    //нашли tab
    if Node.NodeName='text:tab' then
      if not Node.HasAttributes then s:=s+#9; //иначе просто описания стилей

    if (Node is TDOMText) and 
       ((Node.ParentNode.NodeName='text:span') or (Node.ParentNode.NodeName='text:p')
       or (Node.ParentNode.NodeName='text:h')) then
         s:=s+UTF8Encode(Node.TextContent);

    cNode := Node.FirstChild;   // переходим к дочернему узлу
    while cNode <> nil do begin // проходим по всем дочерним узлам
      ProcessNode(cNode,Node_s,kol_,flg_0);
      cNode := cNode.NextSibling;
    end;
  end;

begin
  s:='';
  iNode := XMLDoc.DocumentElement.FirstChild;
  iNode_s:= nil; kol_0:=0; flg_1:=false;
  while iNode <> nil do begin
    ProcessNode(iNode,iNode_s,kol_0,flg_1); // Рекурсия
    iNode := iNode.NextSibling;
  end;
  Result:=s;
end;
qqqq1
новенький
 
Сообщения: 12
Зарегистрирован: 20.08.2010 13:01:46


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 48

Рейтинг@Mail.ru