|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
ошибка при работе с TXMLDocument
Всем доброго времени суток!
Столкнулся с такой проблемой: Необходимо парсить xml файлы, которые содержат в значениях HTML текст. Соответственно внутри значений встречаются тэги, т.е. текст содержит символы < и >, которые воспринимаются как разметка самого xml . В итоге при активации XMLDocument вылетает ошибка. Повлиять на формирование исходных файлов (изначально заменять эти спец символы внутри значений) возможности нет. Как бороться с этой проблемкой может кто подскажет? Может есть какое-то стандартное решение? При том на PHP SimpleXML отрабатывает эти xml-ки без ошибок. Вот пример xml: Код:
<?xml version="1.0" encoding="windows-1251"?> <content> <result>success</result> <data> тут текст, и вдруг html тэг <br> и настает облом... </data> </content> |
#2
|
|||
|
|||
ну, вообще-то, это нарушение спецификации xml. Т.е. это правильно, что TXMLDoc падает на парсинге такого xml. Можно попробовать парсить не через XMLDoc, а через HTMLDoc (это не компонент, надо создать соотв. объект "руками"). Вот пример из одного моего проекта:
Код:
procedure TMonitorItem.SetValuesFromInternetPage(APage : String; AFirst : Boolean = True); var HTMLDoc: OleVariant; HTMLElement: OleVariant; I, J : Integer; Buf, Buf2 : String; AName : String; APrice : Currency; begin AName := 'Item'; APrice := 0.0; HTMLDoc := coHTMLDocument.Create as IHTMLDocument2; HTMLDoc.Write(APage); HTMLDoc.Close; For I := 0 To HTMLDoc.all.length - 1 Do Begin HTMLElement := HTMLDoc.all.item(I); If HTMLElement.tagName = 'META' Then Begin If (IDispatch(HTMLElement) as IHTMLElement5).hasAttribute('name') Then If HTMLElement.getAttribute('name',0) = 'keywords' Then If (IDispatch(HTMLElement) as IHTMLElement5).hasAttribute('content') Then AName := DecodeHtmlText(HTMLElement.getAttribute('content',0)); End; If HTMLElement.tagName = 'SPAN' Then Begin If (IDispatch(HTMLElement) as IHTMLElement5).hasAttribute('class') Then If Not VarIsNull(HTMLElement.getAttribute('className',0)) Then If HTMLElement.getAttribute('className',0) = 'itc-you-pay-price bold' Then Begin buf := HTMLElement.innerHTML; If FormatSettings.DecimalSeparator = ',' Then buf := StringReplace(buf,'.',',',[]) Else buf := StringReplace(buf,',','.',[]); Buf2 := ''; For J := 1 To Length(Buf) Do If CharInSet(Buf[J],['0'..'9',FormatSettings.DecimalSeparator]) Then Buf2 := Buf2 + Buf[J]; APrice := StrToCurr(buf2); End; End; End; If (AName = '') And (APrice = 0.0) Then Raise Exception.Create('Error reading product page.'); FLastPrice := APrice; FLastDate := Now; If AFirst Then Begin FItemName := AName; FInitPrice := APrice; FInitDate := Now; End; end; |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Llirik (09.02.2020)
|
#3
|
|||
|
|||
Спасибо!
Я так и подумал, что придется самому расшифровывать... Проблематика в том, что имена разделов заранее не известны , а вложенность разделов достаточна большая . Но посмотрев внимательнее обнаружил, что такие глюки встречаются лишь в разделах с определенными именами. Я попробую предварительно тупо преобразовать исходный документ к корректной структуре, а именно, вручную найти все разделы с «опасными» именами и заменить внутри их недопустимые символы своими шифровками. А после обработки xml вернуть эти символы восвояси... |