• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

разбор Html

  • Автор темы Gor
  • Дата начала
G

Gor

Ну как разобрать строку я знаю)))

Я так понимаю что на вход в парсер мы можем подать только Stream а не переменную какого либо другого типа, по типу вот так:

Код:
Set html_in=session.CreateStream

If Not html_in.Open(filename$,"UTF-8") Then
Msgbox "Cannot open Doc_1.html", , "Error"
Exit Sub
End If

Set txt_out = session.CreateStream
................................................
Set saxParser=session.CreateSAXParser(html_in, txt_out)


Или можно подать так Set saxParser=session.CreateSAXParser(var1, txt_out) ?
 
A

amigolinx

так а че, можно эти две переменные распихать в две разные stream, чтоб парсеру уже стопудово скормить то что он ест и не задумываться, сработает ли передача ему var :)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 947
609
BIT
246
не забываем про strtoken
тоже юсабельна :)
стриму мона не ассайнить фало, а апосля сохранить с нужной кодировкой (ежели воще нужно сохранять)
Код:
Function SaveStream(stream As NotesStream, path As String, cp As String) As Boolean
On Error Goto errorhandler
Dim ses As New NotesSession
Dim fileStream As NotesStream
Set fileStream=ses.CreateStream
If cp="" Then cp=CodePage
If fileStream.Open(path,cp) Then
If Not stream.IsReadOnly Then
fileStream.Position=0
Call fileStream.Truncate()
stream.Position=0
Dim buffer As String
Do
buffer = stream.ReadText()
Call fileStream.WriteText(buffer)
Loop Until stream.IsEOS
Call stream.Close()
Call fileStream.Close()
SaveStream=True
End If
Else
DbgMsg("bytes:"+Str(stream.Bytes)+ ":Stream openning Error")
End If
ExitFunction:
Exit Function
errorhandler:
Call RaiseError()
SaveStream=False
Resume ExitFunction
End Function
 
G

Gor

Реализовал. Очень понравилось работать с JakartaOroWrapper. Для моей задачи мне показалось самым оптимальным. Достаточно удобно, данные мне необходимые получил в виде массива с которым удобно работать.
 
G

Gor

При тестировании скрипта столкнулся со следующей проблемой... Большинство файлов обрабатываются корректно, но есть достаточно тяжёлые html файлы с большими таблицами.

При обработки одного из файла на Split получаю следующую ошибку:
Array size exceeds maximum limit

Видимо исходный текст который подаётся на вход данной функции слишком большой... Но мне надо разобрать его весь...
Как можно обойти такую ошибку? Каким то образом ещё делить файл?...

Код:
Function getArrValues (sHTML As String) As Variant
Print "Получение значений для полей"

'** everything we'll need to access our Java classes
Dim jSession As JavaSession
Dim oroClass As JavaClass
Dim oro As JavaObject
Dim vector As JavaObject
Dim jError As JavaError
Dim sourceHTML As String

sourceHTML = sHTML
'** get the ORO wrapper class and instantiate an instance of it
Set jSession = New JavaSession
Set oroClass = jSession.GetClass("JakartaOroWrapper")
Set oro = oroClass.CreateObject

'Массивы паттернов с заменяющими их посдстроками 
Dim pattArr (10) As String
Dim substArr (10) As String

pattArr(0)= "</?[a-z]+.*?>"
pattArr(1)= """
pattArr(2)= ""
pattArr(3)= "<"
pattArr(4)= ">"
pattArr(5)= "&"
pattArr(6)= """
pattArr(7)= "®"
pattArr(8)= "©"
pattArr(9)= " "
pattArr(10)= " "


substArr(0) ="~#~"
substArr(1) ={"}
substArr(2) =" "
substArr(3) ="<"
substArr(4) =">"
substArr(5) ="&"
substArr(6) ={"}
substArr(7) ="R"
substArr(8) ="C"
substArr(9) =""
substArr(10) =""



'-------------------------------------------------------------------------------------

'Удаляем тэги и знаки html для разбиения в массив
For i=0 To Ubound(pattArr)
substPattern = pattArr(i)
subst = substArr(i)
sourceHTML= oro.substitute(sourceHTML, substPattern, False, subst, oro.SUBSTITUTE_ALL)
Next

contentArr = Split(sourceHTML, "~#~") ----------------------------Ошибка выскакивает на этой строке
'contentArr=Fulltrim(contentArr)

For i = 0 To Ubound(contentArr)
contentArr(i) = Fulltrim (contentArr(i))
Next

getArrValues = contentArr
End Function
 
O

Omh

Элеменов в array не может быть больше, чем integer.
Т.е. разбивая этот файл, ты получил элементов больше 32 тысяч с копейками.

Можно написать какой-либо свой split (который будет умно разбивать на множественные массивы про достижении лимита)
Можно попробовать юзать вместо массивов list'ы - у них с количество элеменов проблем нету, только тогда вместо одного split'a придётся писать хождение по мукам, точнее по стринг'у твоему.
 
G

Gor

ещё не совсем понятный баг. Имеем массив около 25184 элементов и делаем ему Fulltrim, чтобы убрать все пустые элементы. Лотус у меня после Fulltrim падает))) - Уведомление об ошибке, программа будет закрыта, итд итп...
Нельзя делать Fulltrim на таком количестве элементов в массиве??????? Бага?
версия 7.0.3
 

ToxaRat

Чёрный маг
Green Team
06.11.2007
3 332
42
BIT
0
Gor
если Fulltrim на массиве где есть и стринг и дата и целое то это фича :)
 
A

Akupaka

покажи строчку кода с тримом :) ты вызываешь его как ArrayVariable = FullTrim(ArrayVariable) или иначе?
 
A

amigolinx

А я вот чёто невзлюбил подобного рода операции, при всем их на первый взгляд удобстве - на одной и той же переменной при идентичных условиях часто лезут жутко непонятные траблы - в трех случаях запуска один раз работает как мне надо, один не работает и еще один работает, но уже по своему... Спасаюсь тмпшными переменными типа tmp = Fulltrim(s3), хоть и чуток засоряется от этого код, а может и не только код :).
 
G

Gor

Спасаюсь тмпшными переменными типа tmp = Fulltrim(s3), хоть и чуток засоряется от этого код, а может и не только код .

Я только не совсем понял чем это отличается от s3 = Fulltrim(s3) ?

ну а если уйти мне от Fulltrima, как можно удалить в цикле пустой элемент массива??
типа
Код:
For i = 0 To Ubound(s3)
If s3(i) = "" Then

' здесь надо удалить элемент
End If
Next

Какой функцией можно удалить элемент если он пустой?

Если вставить Erase s3(i) выдаёт ошибку типов
 
N

nvyush

Я только не совсем понял чем это отличается от s3 = Fulltrim(s3) ?

ну а если уйти мне от Fulltrima, как можно удалить в цикле пустой элемент массива??
типа
Код:
For i = 0 To Ubound(s3)
If s3(i) = "" Then

' здесь надо удалить элемент
End If
Next

Какой функцией можно удалить элемент если он пустой?

Если вставить Erase s3(i) выдаёт ошибку типов

Erase - он для очистки всего массива. А удалять элементы массива можно так:

[codebox]Dim j as Integer
j = 0
For i = 0 To Ubound(s3)
If s3(i) <> "" Then
Redim Preserve s4(j)
s4(j) = s3(i)
j = j + 1
End If
Next[/codebox]

На выходе получаем массив s4 без пустот. Кстати, я обычно заменяю в цикле Ubound(...) на значение переменной, т.к. не уверен, что Ubound вычисляется один раз, что-то мне подсказывает, что оно вызывается по числу циклов.
 
A

amigolinx

Я только не совсем понял чем это отличается от s3 = Fulltrim(s3) ?
С виду ничем не отличается за той лишь разницей, что так работает. И к тому же, если пофантазировать на тему внутреннего алгоритма фултрима, то по большому счету кмк он наверное похож как в коде у nvy , где кстати тоже возвращается не изначально переданный массив, а левый, зановосозданный...
 
G

Gor

по ходу появился ещё один вопрос.

Как поменять кодировку значению переменной?
т.е. у меня переменная в кодировке UTF-8 мне надо сменить кодировку на UTF-16

КАк быть? Через NotesStream не получилось. Я так понял что поток можно открыть только из файла.

попробовал функцию слепить, но чёто никак... функция пустоту возвращает

на входе
txt = "один два три" 'в кодировке UTF-8

Код:
Function encode (txt As Variant, session As NotesSession) As String
Dim Stream As NotesStream
Set Stream = session.CreateStream
flag = Stream.Open(txt,"UTF-16")

encode = Stream.ReadText	

End Function
 
A

Akupaka

т.е. у меня переменная в кодировке UTF-8 мне надо сменить кодировку на UTF-16
в чем вопрос не понятно, что значит переменную конвертировать? для чего?
погляди еще LMBCS строки, может поможет
 
G

Gor

Код:
в чем вопрос не понятно, что значит переменную конвертировать? для чего?
погляди еще LMBCS строки, может поможет

Переменная получена парсингом из html файла. Кодировка файла UTF-8, впрочем как и сам поток для получения файла тоже UTF-8.
Соответственно значение переменной тоже в кодировке UTF-8

Конечные результаты мне надо записать в MS SQL базу. Я пользую ODBC.
А MS SQL с кодировкой UTF-8 не дружит совсем.
Вот и хочу перед записью в базу конвертировать полученные переменные в UTF-16
 
T

turumbay

на входе
txt = "один два три" 'в кодировке UTF-8
У строки понятие кодировки отсутствует. Кодировка - набор байт. Обычно Variant array. (byte array)
Соответственно значение переменной тоже в кодировке UTF-8
Вывод неверный. Что есть "кодировка переменной"?

По существу: кодировать строки туда-сюда можно, но вам оно не поможет. Война с odbc ведется другими методами. Поиск по форуму по "odbc" принесет просветление.
Потрепанные в боях ветераны стараюца вообще с ней не связываца и юзают jdbc. А в вашей задаче (работа с файловой системой, парсинг, связь с реляционкой ) - вообще не использовать LS, все от начала до конца сделать на java.
P.S. незатейливые функции для перекодировки. Треба доработки напильником: не работает на длинных файлах, не проверяется валидность имени кодировки, используются variant вместо строгой типизации и пр. и пр.
Код:
Private Const TMP_FILENAME = ' направить куда не жалко.
Function stringToByteArray( i_text As String , i_charset As String ) As Variant
Dim session As New NotesSession
Dim stream As NotesStream
Set stream = session.CreateStream
Call stream.Open( TMP_FILENAME , i_charset )
Call stream.Truncate
Call stream.writeText( i_text )
Call stream.Close

Call stream.Open( TMP_FILENAME )
stringToByteArray = stream.Read() 
Call stream.close
Kill TMP_FILENAME
End Function
Function byteArrayToString( i_byteArray As Variant , i_charSet As String ) As String
Dim session As New NotesSession
Dim stream As NotesStream
Set stream = session.CreateStream
Call stream.Open( TMP_FILENAME )
Call stream.Truncate
Call stream.write( i_byteArray )
Call stream.Close

Call stream.Open( TMP_FILENAME , i_charSet )
byteArrayToString = stream.ReadText
Call stream.close
Kill TMP_FILENAME
End Function


Dim text As String
text = "раз два три"
Dim buffer As Variant
buffer = stringToByteArray( text , "UTF-16" ) ' туда
MessageBox byteArrayToString( buffer , "UTF-16" ) ' обратно
MessageBox byteArrayToString( buffer , "UTF-8" ) ' козябры :-)
 
G

Gor

По существу: кодировать строки туда-сюда можно, но вам оно не поможет. Война с odbc ведется другими методами. Поиск по форуму по "odbc" принесет просветление.
Потрепанные в боях ветераны стараюца вообще с ней не связываца и юзают jdbc. А в вашей задаче (работа с файловой системой, парсинг, связь с реляционкой ) - вообще не использовать LS, все от начала до конца сделать на java.

В Java к сожалению не силён, но чувствую такими темпами да и последними тенденциями развития Lotus-a придётся этот пробел заполнить и усиленно изучать яву...

А эту задачу требоволось решить как можно быстрей, поэтому ушёл от odbc на ADO и проблема с кодировкой ушла.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!