11 php xml dom domdocument
我从其他地方搜索和处理XML文件,并需要使用一些XSLT转换它们.没问题.使用PHP5和DOM库,一切都很简单.工作得很好,到现在为止.今天,时髦的角色在XML文件中 - 来自Word的"智能"引用,它看起来像.无论如何,DOMDocument-> load抱怨他们,说他们不是UTF-8,并指定编码.
请注意,这些XML文件中未指定编码.如果我在标题中添加'encoding ="iso-8859-1"',它可以正常工作.问题是我无法控制这些XML文件.
将文件读入字符串,修改其标题并将其写回另一个位置似乎是我唯一的选择,但我更愿意这样做,而不必使用XML文件的临时副本.有没有办法简单地告诉解析器解析它们就好像它们是iso-8859-1一样?
这对你有用吗?
$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->load($xmlPath);
Run Code Online (Sandbox Code Playgroud)
编辑:由于看起来这不起作用,你可以做的是类似于你现有的方法,但没有临时文件.只使用标准IO操作(file_get_contents()或其他东西)从源读取XML文件,然后对您需要的编码执行任何更改(iconv()或utf8_decode()),然后使用loadXML()
$myXMLString = file_get_contents($xmlPath);
$myXMLString = utf8_decode($myXMLString);
$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->loadXML($myXMLString);
Run Code Online (Sandbox Code Playgroud)
我还没有找到设置默认编码的方法,但在这种情况下恢复模式可能是可行的.
当libxml遇到编码错误并且没有显式设置编码时,它会从unicode/utf8切换到latin1并继续解析文档.但是在解析器上下文中,属性wellFormed设置为0/false.PHP的DOM扩展认为文档有效,如果wellFormed为true 或 DOMDocument对象的属性recover为true.
<?php
// german Umlaut ä in latin1 = 0xE4
$xml = '<foo>'.chr(0xE4).'</foo>';
$doc = new DOMDocument;
$b = $doc->loadxml($xml);
echo 'with doc->recover=false(default) : ', ($b) ? 'success':'failed', "\n";
$doc = new DOMDocument;
$doc->recover = true;
$b = $doc->loadxml($xml);
echo 'with doc->recover=true : ', ($b) ? 'success':'failed', "\n";
Run Code Online (Sandbox Code Playgroud)
版画
Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding !
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 6
with doc->recover=false(default) : failed
Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding !
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 11
with doc->recover=true : success
Run Code Online (Sandbox Code Playgroud)
您仍然会收到警告消息(可以使用@ $ doc-> load()来抑制),它也会显示在内部libxml错误中(仅当解析器从utf8切换到latin1时才会出现一次).此特定错误的错误代码为9(XML_ERR_INVALID_CHAR).
<?php
$xml = sprintf('<foo>
<ae>%s</ae>
<oe>%s</oe>
&
</foo>', chr(0xE4),chr(0xF6));
libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->recover = true;
libxml_clear_errors();
$b = $doc->loadxml($xml);
$invalidCharFound = false;
foreach(libxml_get_errors() as $error) {
if ( 9==$error->code && !$invalidCharFound ) {
$invalidCharFound = true;
echo "found invalid char, possibly harmless\n";
}
else {
echo "hm, that's probably more severe: ", $error->message, "\n";
}
}
Run Code Online (Sandbox Code Playgroud)