解析 XML 文件时如何处理默认命名空间
How to handle default namespaces when parsing XML files
我的 PHP 页面必须解析输入 XML 文件(准确地说是 XLIFF),但是当 [=45= 的根元素中存在默认命名空间时它不起作用] 文件。
我的代码假设需要一个默认命名空间,并且它必须是 urn:oasis:names:tc:xliff:document:1.2
。如果在 XLIFF 根元素中找到,则从那里获取,否则由我的 PHP 代码添加。我认为这行得通,但似乎行不通,目前我必须让它工作的唯一方法是从输入 XLIFF 文件中删除默认命名空间。当然,无论 XLIFF 文件中是否存在默认命名空间,PHP 脚本都应该可以正常工作。
根据默认命名空间是必需的理解,在我的 PHP 脚本中我有:
$xml_file = file_get_contents($pathToInputFile);
if($xml_file === FALSE) {
die("there is a problem to get contents from XLIFF file");
}
$xliffObj = new DOMDocument();
$xliffObj->preserveWhiteSpace = true;
$xliffObj->loadXML($xml_file);
$context = $xliffObj->documentElement;
$xpath = new DOMXPath($xliffObj);
if (isSet($context->getAttributeNode('xmlns')->nodeValue)) {
$ns = $context->getAttributeNode('xmlns')->nodeValue;
echo "The ns is: " . $ns; // line 198
}
else {
$ns = "urn:oasis:names:tc:xliff:document:1.2";
// this works when no default namespaces is defined in the XLIFF file
echo "I have defined the ns as: " . $ns;
}
$xpath->registerNamespace('ns', $ns); // line 208
$tus = $xpath->query('//trans-unit');
var_dump_pre($tus);die;
如果我的输入 XLIFF 文件具有以下内容,则解析工作正常:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">
<xliff xmlns:pisa="http://www.ets.org/pisa" version="1.2">
在那种情况下,输出是
I have defined the ns as: urn:oasis:names:tc:xliff:document:1.2
object(DOMNodeList)#12 (1) {
["length"]=>
int(2)
}
$tus
数组包含 XLIFF 文件中的两个 trans-unit
节点。
但是,当文件有
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">
<xliff xmlns:pisa="http://www.ets.org/pisa" version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
然后什么都没有被提取出来,我保存文件内容的数组是空的(有 NULL
值)。输出为:
The ns is: urn:oasis:names:tc:xliff:document:1.2
object(DOMNodeList)#10 (1) {
["length"]=>
int(0)
}
如您所见,$tus
数组为空。
一个可能的解决方案是在再次添加之前简单地删除命名空间声明,但我想了解问题所在。谢谢。
似乎只有当命名空间出现在 XML 文件中时才需要将命名空间添加到 xpath,因此:
$xpath->registerNamespace('ns', $ns);
$tus = $xpath->query('//ns:trans-unit');
但是,我不确定这在其他情况下是否会适得其反...
当它不存在时,似乎没有必要将它包含在 xpath 表达式中:
#$xpath->registerNamespace('ns', $ns);
$tus = $xpath->query('//trans-unit');
我的 PHP 页面必须解析输入 XML 文件(准确地说是 XLIFF),但是当 [=45= 的根元素中存在默认命名空间时它不起作用] 文件。
我的代码假设需要一个默认命名空间,并且它必须是 urn:oasis:names:tc:xliff:document:1.2
。如果在 XLIFF 根元素中找到,则从那里获取,否则由我的 PHP 代码添加。我认为这行得通,但似乎行不通,目前我必须让它工作的唯一方法是从输入 XLIFF 文件中删除默认命名空间。当然,无论 XLIFF 文件中是否存在默认命名空间,PHP 脚本都应该可以正常工作。
根据默认命名空间是必需的理解,在我的 PHP 脚本中我有:
$xml_file = file_get_contents($pathToInputFile);
if($xml_file === FALSE) {
die("there is a problem to get contents from XLIFF file");
}
$xliffObj = new DOMDocument();
$xliffObj->preserveWhiteSpace = true;
$xliffObj->loadXML($xml_file);
$context = $xliffObj->documentElement;
$xpath = new DOMXPath($xliffObj);
if (isSet($context->getAttributeNode('xmlns')->nodeValue)) {
$ns = $context->getAttributeNode('xmlns')->nodeValue;
echo "The ns is: " . $ns; // line 198
}
else {
$ns = "urn:oasis:names:tc:xliff:document:1.2";
// this works when no default namespaces is defined in the XLIFF file
echo "I have defined the ns as: " . $ns;
}
$xpath->registerNamespace('ns', $ns); // line 208
$tus = $xpath->query('//trans-unit');
var_dump_pre($tus);die;
如果我的输入 XLIFF 文件具有以下内容,则解析工作正常:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">
<xliff xmlns:pisa="http://www.ets.org/pisa" version="1.2">
在那种情况下,输出是
I have defined the ns as: urn:oasis:names:tc:xliff:document:1.2
object(DOMNodeList)#12 (1) { ["length"]=> int(2) }
$tus
数组包含 XLIFF 文件中的两个 trans-unit
节点。
但是,当文件有
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">
<xliff xmlns:pisa="http://www.ets.org/pisa" version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
然后什么都没有被提取出来,我保存文件内容的数组是空的(有 NULL
值)。输出为:
The ns is: urn:oasis:names:tc:xliff:document:1.2
object(DOMNodeList)#10 (1) { ["length"]=> int(0) }
如您所见,$tus
数组为空。
一个可能的解决方案是在再次添加之前简单地删除命名空间声明,但我想了解问题所在。谢谢。
似乎只有当命名空间出现在 XML 文件中时才需要将命名空间添加到 xpath,因此:
$xpath->registerNamespace('ns', $ns);
$tus = $xpath->query('//ns:trans-unit');
但是,我不确定这在其他情况下是否会适得其反...
当它不存在时,似乎没有必要将它包含在 xpath 表达式中:
#$xpath->registerNamespace('ns', $ns);
$tus = $xpath->query('//trans-unit');