Added support for encoding and decoding namespaced xml (xmlns)

This commit is contained in:
Matthew Vickery 2013-08-19 19:03:30 +02:00 committed by Clément Gautier
parent e40e325cdc
commit 9d6b20caa3
2 changed files with 83 additions and 5 deletions

View File

@ -99,9 +99,24 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
// todo: throw an exception if the root node name is not correctly configured (bc) // todo: throw an exception if the root node name is not correctly configured (bc)
if ($rootNode->hasChildNodes()) { if ($rootNode->hasChildNodes()) {
$xpath = new \DOMXPath($dom);
$data = array();
foreach ($xpath->query('namespace::*', $dom->documentElement) as $nsNode) {
$data['@'.$nsNode->nodeName] = $nsNode->nodeValue;
}
if (isset($data['@xmlns:xml'])) {
unset($data['@xmlns:xml']);
}
if (empty($data)) {
return $this->parseXml($rootNode); return $this->parseXml($rootNode);
} }
return array_merge($data, (array) $this->parseXml($rootNode));
}
if (!$rootNode->hasAttributes()) { if (!$rootNode->hasAttributes()) {
return $rootNode->nodeValue; return $rootNode->nodeValue;
} }
@ -227,7 +242,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
{ {
return $name && return $name &&
false === strpos($name, ' ') && false === strpos($name, ' ') &&
preg_match('#^[\pL_][\pL0-9._-]*$#ui', $name); preg_match('#^[\pL_][\pL0-9._:-]*$#ui', $name);
} }
/** /**
@ -281,11 +296,11 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
$data = array(); $data = array();
foreach ($node->attributes as $attrkey => $attr) { foreach ($node->attributes as $attr) {
if (ctype_digit($attr->nodeValue)) { if (ctype_digit($attr->nodeValue)) {
$data['@'.$attrkey] = (int) $attr->nodeValue; $data['@'.$attr->nodeName] = (int) $attr->nodeValue;
} else { } else {
$data['@'.$attrkey] = $attr->nodeValue; $data['@'.$attr->nodeName] = $attr->nodeValue;
} }
} }

View File

@ -203,6 +203,14 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($source, $this->encoder->encode($obj, 'xml')); $this->assertEquals($source, $this->encoder->encode($obj, 'xml'));
} }
public function testEncodeWithNamespace()
{
$source = $this->getNamespacedXmlSource();
$array = $this->getNamespacedArray();
$this->assertEquals($source, $this->encoder->encode($array, 'xml'));
}
public function testEncodeSerializerXmlRootNodeNameOption() public function testEncodeSerializerXmlRootNodeNameOption()
{ {
$options = array('xml_root_node_name' => 'test'); $options = array('xml_root_node_name' => 'test');
@ -253,6 +261,14 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expected, $this->encoder->decode($xml, 'xml')); $this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
} }
public function testDecodeWithNamespace()
{
$source = $this->getNamespacedXmlSource();
$array = $this->getNamespacedArray();
$this->assertEquals($array, $this->encoder->decode($source, 'xml'));
}
public function testDecodeScalarWithAttribute() public function testDecodeScalarWithAttribute()
{ {
$source = '<?xml version="1.0"?>'."\n". $source = '<?xml version="1.0"?>'."\n".
@ -414,6 +430,53 @@ XML;
'</response>'."\n"; '</response>'."\n";
} }
protected function getNamespacedXmlSource()
{
return '<?xml version="1.0"?>'."\n".
'<response xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:media="http://search.yahoo.com/mrss/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007">'.
'<qux>1</qux>'.
'<app:foo>foo</app:foo>'.
'<yt:bar>a</yt:bar><yt:bar>b</yt:bar>'.
'<media:baz><media:key>val</media:key><media:key2>val</media:key2><item key="A B">bar</item>'.
'<item><title>title1</title></item><item><title>title2</title></item>'.
'<Barry size="large"><FooBar gd:id="1"><Baz>Ed</Baz></FooBar></Barry></media:baz>'.
'</response>'."\n";
}
protected function getNamespacedArray()
{
return array(
'@xmlns' => 'http://www.w3.org/2005/Atom',
'@xmlns:app' => 'http://www.w3.org/2007/app',
'@xmlns:media' => 'http://search.yahoo.com/mrss/',
'@xmlns:gd' => 'http://schemas.google.com/g/2005',
'@xmlns:yt' => 'http://gdata.youtube.com/schemas/2007',
'qux' => "1",
'app:foo' => "foo",
'yt:bar' => array("a", "b"),
'media:baz' => array(
'media:key' => "val",
'media:key2' => "val",
'A B' => "bar",
'item' => array(
array(
'title' => 'title1',
),
array(
'title' => 'title2',
)
),
'Barry' => array(
'@size' => 'large',
'FooBar' => array(
'Baz' => 'Ed',
'@gd:id' => 1,
),
),
),
);
}
protected function getObject() protected function getObject()
{ {
$obj = new Dummy(); $obj = new Dummy();