我正在使用xml文件在perl上编写一个chatbot程序,该文件包含包含每个答案的模式--例如,如果用户引入了一个包含模式"you知michael“的字符串,那么其中一个可能的答案应该是”michael jordan是谁?“下面给出了xml代码。
问题是,在上面给出的"michael“示例中,我不知道如何提取用户引入的字符串的第二部分,并将其放入我的输出中?那又是什么
<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>;
}发布于 2014-05-09 22:40:51
<star/>和<star index="2"/>在XML中意味着什么?
根据XML规范第3.1节,语法规则44描述了"Tags for Empty Elements",这意味着元素可能有一些属性,但它没有内容(换句话说,没有后代,没有文本)。
更新
在阅读了OP的更多评论之后,在对这个问题进行了一些新的更新之后,这里有一个可能的解决方案:
test.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");sample.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>https://stackoverflow.com/questions/23574483
复制相似问题