将html嵌套列表解析为perl数组

时间:2013-11-01 15:01:48

标签: perl xml-parsing html-parsing

输入数据:(一些带链接的嵌套列表)

<ul>
    <li><a>1</a>
        <ul>
            <li><a>11</a>
                <ul>
                    <li><a>111</a></li>
                    <li><a>112</a></li>
                    <li><a>113</a>
                    <ul>
                        <li><a>1131</a></li>
                        <li><a>1132</a></li>
                        <li><a>1133</a></li>
                    </ul></li>
                    <li><a>114</a></li>
                    <li><a>115</a></li>
                </ul>
            </li>
            <li><a>12</a>
                <ul>
                    <li><a>121</a>
                    <ul>
                        <li><a>1211</a></li>
                        <li><a>1212</a></li>
                        <li><a>1213</a></li>
                    </ul></li>
                    <li><a>122</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

输出字符串数组:

 1,11,111
 1,11,112
 1,11,113,1131
 1,11,113,1132
 1,11,113,1133
 1,11,114
 1,11,115
 1,12,121,1211
 1,12,121,1212
 1,12,121,1213
 1,12,122

包含

  • 中没有子项的元素文本的完整路径。

    我尝试了什么: 1. XML :: SAX :: ParserFactory

    https://gist.github.com/7266638这里有很多问题。如何检测li是否持久,如何保存路径等我认为它的方法很糟糕。

    1. 它完全不是正则表达式,在现实生活中的例子html更糟糕。很多标签,div,跨度等
    2. 的Dom?但是如何?

  • 1 个答案:

    答案 0 :(得分:3)

    您可以尝试使用XML::Twig模块。它会保存<a>元素中的所有文字,并且仅在<ul>元素之一下没有子<li>时打印它们。

    #!/usr/bin/env perl
    
    use warnings;
    use strict;
    use XML::Twig;
    
    my (@li);
    
    my $twig = XML::Twig->new(
            twig_handlers => {
                    'a' => sub {
                            if ( $_->prev_elt('li') ) { 
                                    push @li, $_->text;
                            }   
                    },  
                    'li' => sub {
                            unless ( $_->children('ul') ) { 
                                    printf qq|%s\n|, join q|,|, @li;
                            }   
                            pop @li;
                    },  
            },  
    )->parsefile( shift );
    

    像以下一样运行:

    perl script.pl xmlfile
    

    产量:

    1,11,111
    1,11,112
    1,11,113,1131
    1,11,113,1132
    1,11,113,1133
    1,11,114
    1,11,115
    1,12,121,1211
    1,12,121,1212
    1,12,121,1213
    1,12,122