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
*