LINUX.ORG.RU

Какой XML парсер на perl лучше всего подходит для задачи или другой способ решения ?


0

1

Есть конфиг файл для freeswitch

<include>
  <extension name="public_did_10012345">
    <condition field="destination_number" expression="^(10012345)$">
    </condition>
  </extension>
  <extension name="public_did_1002">
    <condition field="destination_number" expression="^(1002)$">
      <action application="transfer" data="$1 XML internet-trunks-1002"/>
    </condition>
  </extension>
  <extension name="public_did_1003">
    <condition field="destination_number" expression="^(1003)$">
      <action application="transfer" data="$1 XML internet-trunks-1003"/>
    </condition>
  </extension>
  <extension name="public_did_1004">
    <condition field="destination_number" expression="^(1004)$">
      <action application="transfer" data="$1 XML internet-trunks-1004"/>
    </condition>
  </extension>
  <extension name="public_did_1005">
    <condition field="destination_number" expression="^(1005)$">
      <action application="transfer" data="$1 XML internet-trunks-1004"/>
    </condition>
  </extension>

</include>
Как мне его перегнать в хэш хешей или массив хешей чтобы можно было обращаться к элементам по номеру или по атрибуту элемента name или др.
Т.е нужно сконвертить этот XML в несложную структурку чтобы удобно работать со значениями указав индексы. Залез в модуль XML::DOM но там такого нет или я не могу его готовить. Или посоветуйте как эффективно решить данную задачу.
Может быть и парсер не нужен.
на выходе нужно получить файл со строками вида
internet-trunks-1004;1004,1005
internet-trunks-1003;1003
internet-trunks-1002;1002
;10012345
т.е. в одной строке нужно связать контексты со списком обрабатываемых в нем номеров

★★★★

Последнее исправление: Vlad-76 (всего исправлений: 3)

XML::Simple

anonymous
()
Ответ на: комментарий от belkabelka

если конфиг именно такой, как вы показали (очень ограниченный кусок иксемеля в котором не ожидается хитрых пространств имен) - имеет смысл не париться с иксемелем а просто регулярками разобрать.

belkabelka
()
$ cat config.xml                                                                                           
<?xml version="1.0"?>                                                                                                         
<include>                                                                                                                     
  <extension name="public_did_10012345">                                                                                      
    <condition field="destination_number" expression="^(10012345)$">                                                          
    </condition>                                                                                                              
  </extension>                                                                                                                
  <extension name="public_did_1002">                                                                                          
    <condition field="destination_number" expression="^(1002)$">                                                              
      <action application="transfer" data="$1 XML internet-trunks-1002"/>                                                     
    </condition>
  </extension>
  <extension name="public_did_1003">
    <condition field="destination_number" expression="^(1003)$">
      <action application="transfer" data="$1 XML internet-trunks-1003"/>
    </condition>
  </extension>
  <extension name="public_did_1004">
    <condition field="destination_number" expression="^(1004)$">
      <action application="transfer" data="$1 XML internet-trunks-1004"/>
    </condition>
  </extension>
  <extension name="public_did_1005">
    <condition field="destination_number" expression="^(1005)$">
      <action application="transfer" data="$1 XML internet-trunks-1004"/>
    </condition>
  </extension>

</include>
$ cat pattern.xsl 
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
        <xsl:strip-space elements="*"/>
        <xsl:template match="include">
                <xsl:for-each select="extension">
                        <xsl:value-of select="condition/action/@data" />
                        <xsl:text>;</xsl:text> 
                        <xsl:value-of select="condition/@expression" />
                        <xsl:text>&#xa;</xsl:text> <!-- newline -->
                </xsl:for-each>
        </xsl:template>
</xsl:stylesheet>
$ xsltproc pattern.xsl config.xml 
;^(10012345)$
$1 XML internet-trunks-1002;^(1002)$
$1 XML internet-trunks-1003;^(1003)$
$1 XML internet-trunks-1004;^(1004)$
$1 XML internet-trunks-1004;^(1005)$

Дальнейшее допиливание по вкусу

anonymous
()
Ответ на: комментарий от belkabelka

может и проще
каким образом регулярным выражением из строки

<action application="transfer" data="$1 XML internet-trunks-1002"/>
получить в переменную значение = internet-trunks-1002 ?

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от belkabelka

у меня вот так

my $s2= '  <condition field="destination_number" expression="^(1003)$">';
$s2 =~ s/\s*//; # удаляем пробелы в начале строки
$s2 =~ s/["\/><\^\$()]//g; # удаляем символы
$s2 =~ s/=/ /g; # заменяем символы
$s2 =~ s/^(\w+) *(\w+) *(\w+) *(\w+) *(\w+)/$5/; # оставляем 5 ое слово
print $s2 . "\n";

в принципе понятно

Vlad-76 ★★★★
() автор топика
Ответ на: комментарий от Vlad-76

Вот глупенький, советуют же XSLT-процессор, а он будто ослеп от регекспов.

use strict;
use XML::LibXML;
use XML::LibXSLT;
my $parse = XML::LibXML->new();
my $xslt = XML::LibXSLT->new();
my $xml = $parse->parse_file("config.xml");
my $input = $parse->parse_file ("pattern.xsl");

my $xslt = $xslt->parse_stylesheet($input);
my $result = $xslt->transform($xml);
my $html = $xslt->output_string($result);

open (REPORT, "> test.html")
  or die "Can't open test.html $!\n";

print REPORT $html;

close (REPORT);

pattern.xsl приведён выше. Впихни в него обрезку '$1 XML ' и будет тебе счастье

anonymous
()
Ответ на: комментарий от anonymous

да, анонимус дело говорит, xsl - ънтерпрайзный путь, если твои скрипты кому-то поддерживать надо будет, то лучше тяжелое, но сопровождаемое решение. регекспы для личных нужд

belkabelka
()
Ответ на: комментарий от DELIRIUM

А вот и аналитики подтянулись. Если иксемель формат введен исключительно ради иксемеля, то и поступать с такими данными и разработчиками надо соответственно. К тому же я пояснил ниже, в каком случае это все применимо.

belkabelka
()
Ответ на: комментарий от belkabelka

Мне его и поддерживать, на сервере проблема с перлом, модули не ставятся, сервер переставить не вариант. Для поиска двух строк в бесконечном файле для меня сейчас проще регэкспы + немного логики. Даже если и поддерживать - то смысл двух моих функций понятен до предела.
За совет использовать XSLT-процессор спасибо, просветили. Мощная штука, perl поправлю попробую если будет время
А так и с регэкспами все шуршит
Спасибо всем

Vlad-76 ★★★★
() автор топика
Последнее исправление: Vlad-76 (всего исправлений: 1)
Ответ на: комментарий от belkabelka

что может быть легче и проще чем один регексп, вместо целой библиотеки, в которой хз какие изменения предвидятся, и используется только для одной функции?

anonymous
()
Ответ на: комментарий от anonymous

да ты что, анонимус, затралеть меня вздумал, лалка? одному регекспы не нравятся, другому нравятся, белка везде виновата! предлагаю решение, которое устроит всех - ставим Oracle Database, загружаем xml в поле xmltype, делаем SQL-запрос. Так не будешь ругать белку?

belkabelka
()
Ответ на: комментарий от belkabelka

белка везде виновата!

не вини себя, всё хорошо.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.