Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > XML, XSL > xsltproc |
Автор: SABROG 4.5.2009, 21:47 |
Возился сегодня целый день с xsltproc от libxml2. Проблема такая. Есть xml файл 20Мб. Есть MSSQL сервер. С помощью своего .xsl файла я формирую текстовый файл типа coma separated (почти csv только без кавычек). Нужен этот файлик для BULK INSERT. Проблема возникла, когда в ключах xml файла стали появляться разные спец.символы - запятая, кавычки, пробелы сразу перед текстом и прочее. Всего таких символов-замены штук 10. Изначально я столкнулся с первой проблемой - отсутствие string.replace в xsl 1.0. В xsl 2.0 оно есть, но его не держит xsltproc. На основе шаблонов я сначала нашел многоэтажное решение. Потом узнал о существовании EXSLT. Как вы понимаете, чтобы заменить 10 разных символов в одной строке - приходится строить вавилонскую башню. Ладно бы ключ один был, так их 17. При первых испытаниях произошло следующее: - без replace xml на 20Мб парсится - 15 секунд - с replace (пока всего один символ) - 40 секунд Соответственно, чем больше тем хуже. Но я столкнулся с тем, что символы одинарной и двойной кавычки вообще не могу заменить, т.к. xsltproc ругается на них, даже если я экранирую: "'", '"', '\"', "\'", """, "&#xx;" и т.д. В общем вилы. Думаю сейчас бросить этот злой xslt и парсить самому с помощью C++. Может советы у кого есть какие, по-началу то мне возможность подобного преобразования очень понравилась, особенно скорость (без replace)? |
Автор: sir_nuf_nuf 4.5.2009, 23:59 | ||
как я понял проблему - в делаете CSV файл с помощью XSLT но есть проблема - в CSV попадаю символы которые имеют специальное значение - типа кавычек.. предлагаю: 1) работать с XML с помощью XSLT (а не С++) ибо это удобно. 2) полученый недо-CSV подвергать пост-обработке с целью удаления всех таких артефактов. Я думаю для этого будет удобно использовать регулярные выражения - это будет быстро. с помощью чего конкретно - вам на выбор.. sed, perl, awk и т.д. replace кстати ваши программы можно будет объединить в pipe
|
Автор: SABROG 5.5.2009, 08:34 | ||||
В варианте с пост-обработкой есть проблема - запятые и пробелы. Например:
Если при этом будет такое:
То MSSQL сервер выплюнет ошибку на BULK INSERT. Т.к. существуют пробелы после разделительной запятой и присутствует лишний разделитель запятая в цене 54,30. К тому же "sed -e 's/ba/bu/g'" - заменяет одно вхождение, а у меня массив из 10 таких пар. |
Автор: sir_nuf_nuf 5.5.2009, 09:55 | ||
SABROG, пожалуй да.. запятые стоит эскейпить еще в XSLT. Вообще по идее - у вас должно быть всего 2 запрещенных символа в выводе - это тот который используюется как разделитель строк и тот который используется как разделитель ячеек в строке. Кстати, а может Mysql понимает табуляцию как разделитель? тогда пропроще будет. вот вам две замены.
|
Автор: SABROG 6.5.2009, 08:56 | ||||
Менять MSSQL на MySQL из-за того, что не могу заменить символы в xml ![]() 2 запрещенных ну никак не получается, т.к. всякие "--","&",""","'" - рушат SQL запрос к базе. А он используется уже после того как сделан BULK INSERET в php скрипте-интерфейсе. Например импортировал я название автора "O'Reilly", потом это название берется из базы и передается на страничку в качестве ссылки. Когда я жму на ссылку оно передается уже в другой SQL запрос. А он рушится из-за того, что не экранирован. Нет, конечно можно экранировать все в PHP скрипте, но их таких много сделанных по образу и подобию. Т.ч. мне проще всё лишнее удалить сразу. Но очень расстраивает, что из-за этого скорость парсинга xml файла падает в 2 раза. |
Автор: sir_nuf_nuf 6.5.2009, 11:17 |
Э.. вы меня не поняли. По поводу MSSQL - я просто не правильно прочитал. Менять ничего не надо Каким образом вы копируете данные в базу? http://doc.ddart.net/mssql/sql70/ba-bz_9.htm? Насколько я понял там используется табуляция как разделитель по умолчанию. Т.е. у вас ячейки должны быть раделены табом. Ну вот и разделяйте их так. Совершенно не надо эскейпить все символы. В конце концов.. создайте таблицу (любую) с несколькими колонками, вставьте в нее всякую чепуху со спецсимволами и скопируйте в файл - увидите как все должно выглядеть |
Автор: SABROG 6.5.2009, 12:29 |
У нас FIELDTERMINATOR в запятую выставлен. Но как показали опыты наши партнеры могут в xml запихнуть что-нибудь злое, что даже стандартам не соответствует (например текст на русском в кодировке cp1251 в то время как encode у xml'я стоит UTF-8). |
Автор: sir_nuf_nuf 6.5.2009, 14:31 |
SABROG а) ну лады - в запятую так в запятую. в XSLT - заменяешьвсе запятые и переносы строк на эскейп последовательности. никак не могу понять зачем ВСЕ спецсимволы эскейпить ? ты же делаешь bulk insert, а не SQL запросы склеиваешь б) эх.. ну могу только посучувствовать. А еще ваши партнеры наверняка с этим не будут разбираться ибо нужно это прежде всего вам =) бывает |