Il doit y avoir une définition de l'espace de noms xsi
. Par exemple.
<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"
>
Mise à jour: Vous pourriez write a user defined filter puis laisser le XMLReader use that filter, quelque chose comme:
stream_filter_register('darn', 'DarnFilter');
$src = 'php://filter/read=darn/resource=compress.zlib://something.xml.gz';
$reader->open($src);
Le contenu lu par l'enveloppe de compress.zlib est alors "acheminé" à travers le DarnFilter qui doit trouver le (premier) emplacement où il peut insérer la déclaration xmlns: xsi. Mais cela est tout à fait désordre et prendra un certain se permettre de le faire (par exemple du godet théoriquement pourrait contenir xs
, seau B i:schem
et seau C aLocation="
)
Mise à jour 2: voici un exemple ad hoc d'un filtre dans php qui insère la déclaration d'espace de noms xsi. La plupart du temps non testé (a travaillé avec le test que j'ai couru ;-)) et non documenté. Prenez-le comme preuve de concept et non comme code de production.
<?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;
}
}
Mise à jour 3: Et voici une solution ad hoc écrit en 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('.');
}
}
duplication possible de [Comment lire un fichier XML qui a un espace de noms avec XMLReader?] (Http://stackoverflow.com/questions/3554724/how-to-read-an-xml-file-that-has- a-namespace-with-xmlreader) – VolkerK
Bien que j'aime beaucoup mieux le titre de cette question que le précédent, c'est toujours un doublon. Pardon. – VolkerK
Ce n'est même pas * juste * un doublon, c'est le même utilisateur qui pose à nouveau la même question, dans les deux heures .... – Abel