diff --git a/cake/libs/xml.php b/cake/libs/xml.php index 3f6dd1e1c..4b5699e68 100644 --- a/cake/libs/xml.php +++ b/cake/libs/xml.php @@ -198,7 +198,7 @@ class Xml { } $result = array(); $namespaces = array_merge(array('' => ''), $simpleXML->getNamespaces(true)); - self::_toArray($simpleXML, $result, array_keys($namespaces)); + self::_toArray($simpleXML, $result, '', array_keys($namespaces)); return $result; } @@ -207,19 +207,23 @@ class Xml { * * @param object $xml SimpleXMLElement object * @param array $parentData Parent array with data + * @param string $ns Namespace of current child * @param array $namespaces List of namespaces in XML * @return void */ - protected static function _toArray($xml, &$parentData, $namespaces) { + protected static function _toArray($xml, &$parentData, $ns, $namespaces) { $data = array(); foreach ($namespaces as $namespace) { foreach ($xml->attributes($namespace, true) as $key => $value) { + if (!empty($namespace)) { + $key = $namespace . ':' . $key; + } $data['@' . $key] = (string)$value; } 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; } - $name = $xml->getName(); + if (!empty($ns)) { + $ns .= ':'; + } + $name = $ns . $xml->getName(); if (isset($parentData[$name])) { if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) { $parentData[$name] = array($parentData[$name]); diff --git a/cake/tests/cases/libs/xml.test.php b/cake/tests/cases/libs/xml.test.php index 80c06a7d8..61c88e233 100644 --- a/cake/tests/cases/libs/xml.test.php +++ b/cake/tests/cases/libs/xml.test.php @@ -397,7 +397,7 @@ class XmlTest extends CakeTestCase { $expected = array( 'root' => array( 'tag' => 'defect', - 'bug' => 1 + 'cake:bug' => 1 ) ); $this->assertEqual(Xml::toArray($obj), $expected); @@ -414,6 +414,10 @@ class XmlTest extends CakeTestCase { $this->assertEqual($rssAsArray['rss']['@version'], '2.0'); $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( 'title' => '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'); $expected = array( 'Envelope' => array( - '@encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', - 'Body' => array( - 'GetStockPrice' => array( - 'StockName' => 'IBM' + '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', + 'soap:Body' => array( + 'm:GetStockPrice' => array( + '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'); $expected = array( 'Envelope' => array( - '@encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', - 'Body' => array( - 'GetStockPriceResponse' => array( - 'Price' => '34.5' + '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding', + 'soap:Body' => array( + 'm:GetStockPriceResponse' => array( + 'm:Price' => '34.5' ) ) ) @@ -522,6 +526,50 @@ class XmlTest extends CakeTestCase { $this->assertEqual(Xml::toArray($xmlResponse), $expected); } +/** + * testNamespace + * + * @retun void + */ + public function testNamespace() { + $xmlResponse = Xml::build('goodbadTag without ns'); + $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('1'); + $expected = array( + 'root' => array( + 'ns:tag' => array( + '@id' => '1' + ), + 'tag' => array( + 'id' => '1' + ) + ) + ); + $this->assertEqual(Xml::toArray($xmlResponse), $expected); + + $xmlResponse = Xml::build('1'); + $expected = array( + 'root' => array( + 'ns:attr' => '1' + ) + ); + $this->assertEqual(Xml::toArray($xmlResponse), $expected); + + $xmlResponse = Xml::build('1'); + $this->assertEqual(Xml::toArray($xmlResponse), $expected); + } + /** * data provider for toArray() failures *