需要定义xsi
命名空间。例如。
<ShowVehicleRemarketing
environment="Production"
lang="en-CA"
release="8.1-Lite"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.starstandards.org/STAR/STAR/Rev4.2.4/BODs/Standalone/ShowVehicleRemarketing.xsd"
>
更新:你可以write a user defined filter然后让XMLReader的use that filter,是这样的:
stream_filter_register('darn', 'DarnFilter');
$src = 'php://filter/read=darn/resource=compress.zlib://something.xml.gz';
$reader->open($src);
由compress.zlib包装读取其中的内容又被 “路由” 通过DarnFilter这必须找到可以插入xmlns:xsi声明的(第一个)位置。但是,这是相当混乱,并会采取一些负担得起这样做的权利(如理论上桶中可能含有xs
,斗乙i:schem
和C桶aLocation="
)
更新2:这里是一个过滤器的一个特设的例子在PHP中插入xsi命名空间声明。大部分未经测试(与我跑过的一次测试一起工作;-))和无证件。把它当作一个概念验证而不是生产代码。
<?php
stream_filter_register('darn', 'DarnFilter');
$src = 'php://filter/read=darn/resource=compress.zlib://d:/test.xml.gz';
$r = new XMLReader;
$r->open($src);
while($r->read()) {
echo '.';
}
class DarnFilter extends php_user_filter {
protected $buffer='';
protected $status = PSFS_FEED_ME;
public function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
$consumed += $bucket->datalen;
if (PSFS_PASS_ON == $this->status) {
// we're already done, just copy the content
stream_bucket_append($out, $bucket);
}
else {
$this->buffer .= $bucket->data;
if ($this->foo()) {
// first element found
// send the current buffer
$bucket->data = $this->buffer;
$bucket->datalen = strlen($bucket->data);
stream_bucket_append($out, $bucket);
$this->buffer = null;
// no need for further processing
$this->status = PSFS_PASS_ON;
}
}
}
return $this->status;
}
/* looks for the first (root) element in $this->buffer
* if it doesn't contain a xsi namespace decl inserts it
*/
protected function foo() {
$rc = false;
if (preg_match('!<([^?>\s]+)\s?([^>]*)>!', $this->buffer, $m, PREG_OFFSET_CAPTURE)) {
$rc = true;
if (false===strpos($m[2][0], 'xmlns:xsi')) {
echo ' inserting xsi decl ';
$in = '<'.$m[1][0]
. ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
. $m[2][0] . '>';
$this->buffer = substr($this->buffer, 0, $m[0][1])
. $in
. substr($this->buffer, $m[0][1] + strlen($m[0][0]));
}
}
return $rc;
}
}
更新3:下面是用C#编写
XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
// prime the XMLReader with the xsi namespace
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
using (XmlReader reader = XmlTextReader.Create(
new GZipStream(new FileStream(@"\test.xml.gz", FileMode.Open, FileAccess.Read), CompressionMode.Decompress),
new XmlReaderSettings(),
new XmlParserContext(null, nsmgr, null, XmlSpace.None)
)) {
while (reader.Read())
{
System.Console.Write('.');
}
}
可能重复的[如何读取具有XMLReader命名空间的XML文件?](http://stackoverflow.com/questions/3554724/how-to-read-an-xml-file-that-has- a-namespace-with-xmlreader) – VolkerK 2010-08-24 11:03:47
尽管我比以前更喜欢这个问题的标题,但它仍然是重复的。抱歉。 – VolkerK 2010-08-24 11:07:25
它甚至不*只是*一个重复的,它是同一用户在两个小时内再次询问同一个问题...... – Abel 2010-08-24 14:52:18