5

我正在使用这样的 XML:(它是 epub 书中的标准container.xml )

<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="OEBPS/9780765348210.opf" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>

我正在尝试使用 PHP 解析它。到目前为止,这是我的代码:

$c = new DOMDocument();
$c->load($filename);
$x = new DOMXPath($c);
//fine up to here!

//is this even what I'm supposed to be doing?
$x->registerNamespace('epub', 'urn:oasis:names:tc:opendocument:xmlns:container');
$root = $x->query('/epub:container/epub:rootfiles/epub:rootfile');

//fine down from here!
$opf = $root->item(0)->getAttribute('full-path'); //I know I should check if the element's there and if it has the attribute. Not important.

我的问题是:有没有办法不打那个registerNamespace电话?我不确定不同的 epub 是否设置了这个值有点不同,我需要这个代码来处理我扔给它的任何 epub。

4

2 回答 2

4

阿法克:没有。XML 文档可能会出现名称冲突,因此使用了名称空间。如果不注册一个或多个名称空间并为它们设置前缀,就无法在 XML 文档上使用 XPath。

在您的示例中,XML 声明了一个默认命名空间(xmlns="<namespace identifier>"),在这种情况下,所有没有一个或多个命名空间前缀的元素都将属于默认命名空间。只要您知道要查找的内容在此默认命名空间中,那么就会有一些更简单的事情:您可以做的不是硬编码默认命名空间并像这样获取它:

// ... load the DOMDocument ...

$defaultNamespace = $c->lookupNamespaceURI($c->namespaceURI);
$x->registerNamespace('epub', $defaultNamespace);

// ... now query like in your example
$root = $x->query('/epub:container/epub:rootfiles/epub:rootfile');
于 2013-09-09T16:56:53.210 回答
1

为了详细说明 Max 的响应,如果您的 XML 文档本身没有声明默认命名空间,那么从技术上讲,您可以避免在 DOMXPath 上注册命名空间。这意味着文档中的所有元素都不会与任何命名空间相关联。但是,由于您使用的似乎是行业标准,我猜想在 XML 文档本身中声明该名称空间是必要的。如果您的 XML 文档如下所示,那么您可以跳过 registerNamespace 声明,而不必在查询中使用命名空间前缀“epub”。

<?xml version="1.0"?>
<container version="1.0">
   <rootfiles>
      <rootfile full-path="OEBPS/9780765348210.opf" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>

但是,大多数不是在单个组织内专门使用的 XML 文档都将声明一个默认名称空间。

于 2019-05-09T00:01:30.617 回答