如何使用Perl';具有非英语元素名称的XML::XPath?
当某些元素的名称不是英文时,如何处理 我使用草莓Perl 我从web上获得如何使用Perl';具有非英语元素名称的XML::XPath?,xml,perl,xpath,utf-8,Xml,Perl,Xpath,Utf 8,当某些元素的名称不是英文时,如何处理 我使用草莓Perl 我从web上获得employees.xml和train_xml.pl,它们工作得很好 但是当我添加一些汉字时,我得到以下错误: D:/草莓/perl/site/lib/XML/XPath/Parser.pm第189行的骰子中的宽字符。 Query: /employees/employee[@age="30"]/工作... ..............................^^^ Invalid query somewhere a
employees.xml
和train_xml.pl
,它们工作得很好
但是当我添加一些汉字时,我得到以下错误:
D:/草莓/perl/site/lib/XML/XPath/Parser.pm第189行的骰子中的宽字符。
Query:
/employees/employee[@age="30"]/工作...
..............................^^^
Invalid query somewhere around here (I think)
我怎样才能解决这个问题
employees.xml
:
linux
美国
教师
雨衣
美国
窗户
美国
train_xml.pl
:
use Encode;
use XML::XPath->new;
use utf8;
my $xp=XML::XPath->new(filename=>"employees.xml");
print $xp->findvalue('/employees/employee[@age="10"]/name'),"\n";
my $path1 = '/employees/employee[@age="30"]/工作';
print $xp->findvalue($path1),"\n";
您可以使用:
输出:
$ ./a a.xml
mac
教师
$ ./a a.xml
mac
教师
如果您想继续使用(buggy、较慢且使用范围远小于buggy),可以使用以下选项:
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open ':std', ':encoding(UTF-8)';
use feature qw( say );
use XML::XPath qw( );
{ # Monkeypatch XML::XPath.
package XML::XPath::Parser;
# Colon removed from these definitions.
my $NameStartCharClassBody = "a-zA-Z_\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}";
my $NameCharClassBody = "${NameStartCharClassBody}\\-.0-9\\xB7\\x{300}-\\x{36F}\\x{203F}-\\x{2040}";
my $Name = "(?:[$NameStartCharClassBody][$NameCharClassBody]*)";
$NCName = $Name;
$QName = "$NCName(?::$NCName)?";
$NCWild = "${NCName}:\\*";
}
{
my $doc = XML::XPath->new(filename => $ARGV[0]);
say $doc->findvalue('/employees/employee[@age="10"]/name');
say $doc->findvalue('/employees/employee[@age="30"]/工作');
}
输出:
$ ./a a.xml
mac
教师
$ ./a a.xml
mac
教师
您应该始终毫无例外地发布您运行的实际代码,而不是胡言乱语,如:
use XML::XPath->new;
现在,关于这个问题,我相当肯定这是由以下原因造成的:
由于我不熟悉的原因,它要求元素的第一个字符仅限于一组英文字母和。
。下面是一个简单的测试用例:
#!/usr/bin/env perl
use v5.14;
use strict;
use warnings;
use utf8;
use open qw(:std :encoding(UTF-8));
use XML::XPath;
my $xp = XML::XPath->new(ioref => \*DATA );
my $good_path = '/employees/employee[@age="30"]/yağcı';
my $bad_path = '/employees/employee[@age="30"]/şımarık';
say $xp->findvalue($good_path);
say $xp->findvalue($bad_path);
__DATA__
<?xml version="1.0" encoding="utf-8" ?>
<employees>
<employee age="30">
<şımarık>değil</şımarık>
<yağcı>değil</yağcı>
</employee>
</employees>
如果我将该模式更改为:
我得到输出:
C:\…\>perlx.pl
德伊尔
德伊尔
使用您的原始数据,我得到:
değil
教师
在做出适当的更改之后
这不是正确的模式,但我这样做是为了确保我对原因的预感是正确的,因为我做出了尽可能小的改变。正确的规格是:
这个。您可以下载或更高版本的测试。第一次查询的结果正确吗?看起来它只是在解析第二个查询时遇到了问题,而不是您的XMLYes有任何问题。是的,来自web的第一个查询是正确的。我添加的第二个问题不正确。非常感谢!你的两个答案对我很有启发性。幸运的是::Parser将模式存储在全局变量中!谢谢你的详细解释。
$NCName = '(\w[\w\\.\\-]*)';
Name ::= NameStartChar (NameChar)*
NameStartChar ::= ":" | [A-Z] | "_" | [a-z] |
[#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] |
[#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] |
[#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] |
[#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 |
[#x0300-#x036F] | [#x203F-#x2040]