1

我正在使用 xml 文件在 perl 上编写一个聊天机器人程序,该文件包含每个答案的模式,例如,如果用户引入一个包含模式“你知道迈克尔乔丹”的字符串,则可能的答案之一应该是“谁是迈克尔乔丹?”。xml代码如下。

问题是,我不知道如何提取用户引入的字符串的第二部分,在上面给出的示例中“michael jordan”并将其放在我的输出中???以及做什么

<star/><star index="2"/>在 XML 中表示 ???

谢谢

<category> 
<pattern>you know *</pattern>
  <template> 
    <random> 
      <li>No, who is?</li>
      <li>who is <star/>?</li>
      <li>i don't know.</li>
    </random>
  </template>
</category>

perl 代码:

my $parser  = XML::LibXML->new();
my $xmlfile = $parser->parse_file( $ARGV[0] );

my %palabras;
my @respuestas;

$xmlfile = $xmlfile->getDocumentElement();

my @kids = $xmlfile->findnodes('//category');

foreach my $child (@kids) {
    my $pattern = $child->findvalue('pattern');

    @respuestas = $child->findnodes('template/random/li');

    for my $answer (@respuestas) {
        push @{ $palabras{$pattern} }, $answer->textContent;
    }

}

my $cadena = <STDIN>;

while ( $cadena ne "adios\n" ) {
    foreach my $pattern ( keys %palabras ) {
        if ( index( uc $cadena, $pattern ) != -1 ) {
            @respuestas = @{ $palabras{$pattern} };
            my $n = int rand( $#respuestas + 1 );
            print $respuestas[$n] . "\n";    #
            last;
        }
    }

    $cadena = <STDIN>;
}
4

1 回答 1

0

<star/>以及<star index="2"/>在 XML 中是什么意思?

根据XML 规范第 3.1 节,语法规则 [44] 描述"Tags for Empty Elements"了元素可能具有某些属性,但没有内容(换句话说,没有后代,没有文本)。

更新

在阅读了 OP 的更多评论并对该问题进行了一些新的更新之后,这是一种可能的解决方案:

测试.pl

#!/usr/bin/env perl
package Bot::Find::Answer;
use strict;
use warnings;
use XML::LibXML;
use Data::Dumper;
use List::Util qw/first/;

#### Constructor
#### Get path to XML with question/answer data.
#### Calls init to process data.
#### Returns new instance of object Bot::Find::Answer
sub new {
    my ($class,$xml_path) = @_;
    my $obj = bless {
        #### Path on disk to XML
        xml_path => $xml_path,
        #### Knowlege Base
        kb       => [],
    }, $class;
    $obj->init();
    return $obj;
};

#### Parse XML
#### Get stars in question and replace them with regex capture groups
#### Get all answers for each question and store them.
#### Store everything in $self->{kb}
sub init {
    my ($self) = @_;

    my $kb = $self->{kb};

    my $xml = XML::LibXML->load_xml(
        location => $self->{xml_path}
    );

    for my $cat ($xml->findnodes('//category')) {
        my $question_pattern = ($cat->findnodes('pattern'))[0]->textContent;
        $question_pattern =~ s/\*/(.*)/g;
        my @answers = 
        map { $_->textContent }
        $cat->findnodes('template/random/li');

        push @$kb, {
            p => $question_pattern,
            a => \@answers
        };
    };

};


#### Get first category for which the question matches the associated pattern
#### Pick a random answer
#### Fill random answer with captures from pattern.
#### Return answer
sub compute_answer {
    my ($self,$q) = @_;
    my $kb = $self->{kb};
    my $cat_found = first { $q =~ /$_->{p}/ } @$kb;
    my $idx = int(rand(@{ $cat_found->{a}}));
    my $picked_answer = $cat_found->{a}->[$idx];
    my (@captures) = $q =~ $cat_found->{p};
    for my $i (0..(-1+@captures)) {
        my $j = $i + 1;
        my $capture_val = $captures[$i];
        $picked_answer =~ s/\[capture$j\]/$capture_val/g;
    };

    return $picked_answer;
}

package main;

my $o = Bot::Find::Answer->new('sample.xml');
print $o->compute_answer("you know michael jordan");

示例.xml

<?xml version="1.0" encoding="iso-8859-1"?>
<data>
    <category> 
        <pattern>you know *</pattern>
        <template> 
            <random> 
                <li>No, who is [capture1]?</li>
                <li>who is [capture1]?</li>
                <li>i don't know.</li>
            </random>
        </template>
    </category>
    <category> 
        <pattern>name a country from south america</pattern>
        <template> 
            <random> 
                <li>ecuador</li>
                <li>uruguay</li>
                <li>chile</li>
                <li>panama</li>
                <li>brazil</li>
            </random>
        </template>
    </category>
</data>
于 2014-05-09T22:40:51.433 回答