Perl,LibXML和架构 [英] Perl, LibXML and Schemas

查看:83
本文介绍了Perl,LibXML和架构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个示例Perl脚本,该脚本试图根据模式加载和验证文件,它们询问各种节点.

I have an example Perl script which I am trying to load and validate a file against a schema, them interrogate various nodes.

#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;

my $filename = 'source.xml';
my $xml_schema = XML::LibXML::Schema->new(location=>'library.xsd');
my $parser = XML::LibXML->new ();
my $doc = $parser->parse_file ($filename);

eval {
    $xml_schema->validate ($doc);
};

if ($@) {
    print "File failed validation: $@" if $@;
}

eval {
    print "Here\n";
    foreach my $book ($doc->findnodes('/library/book')) {
        my $title = $book->findnodes('./title');
        print $title->to_literal(), "\n";

    }
};

if ($@) {
    print "Problem parsing data : $@\n";
}

不幸的是,尽管它可以很好地验证XML文件,但是它找不到任何$ book项目,因此也没有打印出任何内容.

Unfortunately, although it is validating the XML file fine, it is not finding any $book items and therefore not printing out anything.

如果我从XML文件中删除了架构,从PL文件中删除了验证,那么它将正常工作.

If I remove the schema from the XML file and the validation from the PL file then it works fine.

我正在使用默认名称空间.如果将其更改为不使用默认名称空间(xmlns:lib ="http://libs.domain.com",并用lib为XML文件中的所有项目添加前缀,然后更改XPath表达式以包含名称空间前缀(/lib: library/lib:book),然后它又可以正常工作了.

I am using the default namespace. If I change it to not use the default namespace (xmlns:lib="http://libs.domain.com" and prefix all items in the XML file with lib and change the XPath expressions to include the namespace prefix (/lib:library/lib:book) then it again works file.

为什么?我想念什么?

XML:

<?xml version="1.0" encoding="utf-8"?>
<library xmlns="http://lib.domain.com" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://lib.domain.com .\library.xsd">
    <book>
        <title>Perl Best Practices</title>
        <author>Damian Conway</author>
        <isbn>0596001738</isbn>
        <pages>542</pages>
        <image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif" width="145" height="190"/>
    </book>
    <book>
        <title>Perl Cookbook, Second Edition</title>
        <author>Tom Christiansen</author>
        <author>Nathan Torkington</author>
        <isbn>0596003137</isbn>
        <pages>964</pages>
        <image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif" width="145" height="190"/>
    </book>
    <book>
        <title>Guitar for Dummies</title>
        <author>Mark Phillips</author>
        <author>John Chappell</author>
        <isbn>076455106X</isbn>
        <pages>392</pages>
        <image src="http://media.wiley.com/product_data/coverImage/6X/07645510/076455106X.jpg" width="100" height="125"/>
    </book>
</library>

XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://lib.domain.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://lib.domain.com">
    <xs:attributeGroup name="imagegroup">
        <xs:attribute name="src" type="xs:string"/>
        <xs:attribute name="width" type="xs:integer"/>
        <xs:attribute name="height" type="xs:integer"/>
    </xs:attributeGroup>
    <xs:element name="library">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string"/>
                            <xs:element maxOccurs="unbounded" name="author" type="xs:string"/>
                            <xs:element name="isbn" type="xs:string"/>
                            <xs:element name="pages" type="xs:integer"/>
                            <xs:element name="image">
                                <xs:complexType>
                                    <xs:attributeGroup ref="imagegroup"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

推荐答案

来自 XML :: LibXML文档:

关于XPath的一个常见错误是 假设节点测试包括 没有前缀匹配的元素名称 默认名称空间中的元素. 这个假设是错误的-通过XPath 规范,这样的节点测试可以 仅匹配不存在的元素 (即null)命名空间. ...(和 稍后)……推荐的方法是 使用 XML :: LibXML :: XPathContext 模块

A common mistake about XPath is to assume that node tests consisting of an element name with no prefix match elements in the default namespace. This assumption is wrong - by XPath specification, such node tests can only match elements that are in no (i.e. null) namespace. ...(and later)... ...The recommended way is to use the XML::LibXML::XPathContext module

因此,从XPath的角度来看,没有默认"名称空间...对于任何非空名称空间,您必须在XPath中指定它.通过XML :: LibXML :: XPathContext模块,您可以为要在XPath表达式中使用的任何命名空间创建前缀.

So, from the perspective of XPath, there is no "default" namespace...for any non-null namespace, you have to specify it in your XPath. The XML::LibXML::XPathContext module lets you create a prefix for any namespace to use in your XPath expression.

这篇关于Perl,LibXML和架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆