![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Всем доброго времени суток!
Столкнулся с такой проблемой: Необходимо парсить 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 вернуть эти символы восвояси... |