Support to namespaces in Xml::toArray().

This commit is contained in:
Juan Basso 2010-09-07 00:31:50 -03:00
parent 5f902d42e0
commit c1a75cbc47
2 changed files with 68 additions and 13 deletions

View file

@ -198,7 +198,7 @@ class Xml {
} }
$result = array(); $result = array();
$namespaces = array_merge(array('' => ''), $simpleXML->getNamespaces(true)); $namespaces = array_merge(array('' => ''), $simpleXML->getNamespaces(true));
self::_toArray($simpleXML, $result, array_keys($namespaces)); self::_toArray($simpleXML, $result, '', array_keys($namespaces));
return $result; return $result;
} }
@ -207,19 +207,23 @@ class Xml {
* *
* @param object $xml SimpleXMLElement object * @param object $xml SimpleXMLElement object
* @param array $parentData Parent array with data * @param array $parentData Parent array with data
* @param string $ns Namespace of current child
* @param array $namespaces List of namespaces in XML * @param array $namespaces List of namespaces in XML
* @return void * @return void
*/ */
protected static function _toArray($xml, &$parentData, $namespaces) { protected static function _toArray($xml, &$parentData, $ns, $namespaces) {
$data = array(); $data = array();
foreach ($namespaces as $namespace) { foreach ($namespaces as $namespace) {
foreach ($xml->attributes($namespace, true) as $key => $value) { foreach ($xml->attributes($namespace, true) as $key => $value) {
if (!empty($namespace)) {
$key = $namespace . ':' . $key;
}
$data['@' . $key] = (string)$value; $data['@' . $key] = (string)$value;
} }
foreach ($xml->children($namespace, true) as $child) { foreach ($xml->children($namespace, true) as $child) {
self::_toArray($child, $data, $namespaces); self::_toArray($child, $data, $namespace, $namespaces);
} }
} }
@ -230,7 +234,10 @@ class Xml {
$data['@'] = $asString; $data['@'] = $asString;
} }
$name = $xml->getName(); if (!empty($ns)) {
$ns .= ':';
}
$name = $ns . $xml->getName();
if (isset($parentData[$name])) { if (isset($parentData[$name])) {
if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) { if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) {
$parentData[$name] = array($parentData[$name]); $parentData[$name] = array($parentData[$name]);

View file

@ -397,7 +397,7 @@ class XmlTest extends CakeTestCase {
$expected = array( $expected = array(
'root' => array( 'root' => array(
'tag' => 'defect', 'tag' => 'defect',
'bug' => 1 'cake:bug' => 1
) )
); );
$this->assertEqual(Xml::toArray($obj), $expected); $this->assertEqual(Xml::toArray($obj), $expected);
@ -414,6 +414,10 @@ class XmlTest extends CakeTestCase {
$this->assertEqual($rssAsArray['rss']['@version'], '2.0'); $this->assertEqual($rssAsArray['rss']['@version'], '2.0');
$this->assertEqual(count($rssAsArray['rss']['channel']['item']), 2); $this->assertEqual(count($rssAsArray['rss']['channel']['item']), 2);
$atomLink = array('@href' => 'http://bakery.cakephp.org/articles/rss', '@rel' => 'self', '@type' => 'application/rss+xml');
$this->assertEqual($rssAsArray['rss']['channel']['atom:link'], $atomLink);
$this->assertEqual($rssAsArray['rss']['channel']['link'], 'http://bakery.cakephp.org/');
$expected = array( $expected = array(
'title' => 'Alertpay automated sales via IPN', 'title' => 'Alertpay automated sales via IPN',
'link' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn', 'link' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn',
@ -498,10 +502,10 @@ class XmlTest extends CakeTestCase {
$xmlRequest = Xml::build(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'fixtures' . DS . 'soap_request.xml'); $xmlRequest = Xml::build(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'fixtures' . DS . 'soap_request.xml');
$expected = array( $expected = array(
'Envelope' => array( 'Envelope' => array(
'@encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
'Body' => array( 'soap:Body' => array(
'GetStockPrice' => array( 'm:GetStockPrice' => array(
'StockName' => 'IBM' 'm:StockName' => 'IBM'
) )
) )
) )
@ -511,10 +515,10 @@ class XmlTest extends CakeTestCase {
$xmlResponse = Xml::build(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'fixtures' . DS . 'soap_response.xml'); $xmlResponse = Xml::build(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'fixtures' . DS . 'soap_response.xml');
$expected = array( $expected = array(
'Envelope' => array( 'Envelope' => array(
'@encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
'Body' => array( 'soap:Body' => array(
'GetStockPriceResponse' => array( 'm:GetStockPriceResponse' => array(
'Price' => '34.5' 'm:Price' => '34.5'
) )
) )
) )
@ -522,6 +526,50 @@ class XmlTest extends CakeTestCase {
$this->assertEqual(Xml::toArray($xmlResponse), $expected); $this->assertEqual(Xml::toArray($xmlResponse), $expected);
} }
/**
* testNamespace
*
* @retun void
*/
public function testNamespace() {
$xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:tag id="1"><child>good</child><otherchild>bad</otherchild></ns:tag><tag>Tag without ns</tag></root>');
$expected = array(
'root' => array(
'ns:tag' => array(
'@id' => '1',
'child' => 'good',
'otherchild' => 'bad'
),
'tag' => 'Tag without ns'
)
);
$this->assertEqual(Xml::toArray($xmlResponse), $expected);
$xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:tag id="1" /><tag><id>1</id></tag></root>');
$expected = array(
'root' => array(
'ns:tag' => array(
'@id' => '1'
),
'tag' => array(
'id' => '1'
)
)
);
$this->assertEqual(Xml::toArray($xmlResponse), $expected);
$xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:attr>1</ns:attr></root>');
$expected = array(
'root' => array(
'ns:attr' => '1'
)
);
$this->assertEqual(Xml::toArray($xmlResponse), $expected);
$xmlResponse = Xml::build('<root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>');
$this->assertEqual(Xml::toArray($xmlResponse), $expected);
}
/** /**
* data provider for toArray() failures * data provider for toArray() failures
* *