Necesito parsear unos xml que me devuelve un webservice.
Encontré
ésta clase que parsea los xml y funciona bien.
Código PHP:
class MyDOMDocument extends DOMDocument
{
public function toArray(DOMNode $oDomNode = null)
{
// return empty array if dom is blank
if (is_null($oDomNode) && !$this->hasChildNodes()) {
return array();
}
$oDomNode = (is_null($oDomNode)) ? $this->documentElement : $oDomNode;
if (!$oDomNode->hasChildNodes()) {
$mResult = $oDomNode->nodeValue;
} else {
$mResult = array();
foreach ($oDomNode->childNodes as $oChildNode) {
// how many of these child nodes do we have?
// this will give us a clue as to what the result structure should be
$oChildNodeList = $oDomNode->getElementsByTagName($oChildNode->nodeName);
$iChildCount = 0;
// there are x number of childs in this node that have the same tag name
// however, we are only interested in the # of siblings with the same tag name
foreach ($oChildNodeList as $oNode) {
if ($oNode->parentNode->isSameNode($oChildNode->parentNode)) {
$iChildCount++;
}
}
$mValue = $this->toArray($oChildNode);
$sKey = ($oChildNode->nodeName{0} == '#') ? 0 : $oChildNode->nodeName;
$mValue = is_array($mValue) ? $mValue[$oChildNode->nodeName] : $mValue;
// how many of thse child nodes do we have?
if ($iChildCount > 1) { // more than 1 child - make numeric array
$mResult[$sKey][] = $mValue;
} else {
$mResult[$sKey] = $mValue;
}
}
// if the child is <foo>bar</foo>, the result will be array(bar)
// make the result just 'bar'
if (count($mResult) == 1 && isset($mResult[0]) && !is_array($mResult[0])) {
$mResult = $mResult[0];
}
}
// get our attributes if we have any
$arAttributes = array();
if ($oDomNode->hasAttributes()) {
foreach ($oDomNode->attributes as $sAttrName=>$oAttrNode) {
// retain namespace prefixes
$arAttributes["@{$oAttrNode->nodeName}"] = $oAttrNode->nodeValue;
}
}
// check for namespace attribute - Namespaces will not show up in the attributes list
if ($oDomNode instanceof DOMElement && $oDomNode->getAttribute('xmlns')) {
$arAttributes["@xmlns"] = $oDomNode->getAttribute('xmlns');
}
if (count($arAttributes)) {
if (!is_array($mResult)) {
$mResult = (trim($mResult)) ? array($mResult) : array();
}
$mResult = array_merge($mResult, $arAttributes);
}
$arResult = array($oDomNode->nodeName=>$mResult);
return $arResult;
}
}
El problema viene cuando hay etiquetas con el mismo nombre. Sólo me devuelve una.
He estado haciendo pruebas pero no consigo resolverlo.
Código XML:
Ver original<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="http://www.eurid.eu/xml/epp/epp-1.0" xmlns:domain="http://www.eurid.eu/xml/epp/domain-1.0" xmlns:extendedInfo="http://www.eurid.eu/xml/epp/extendedInfo-1.0">
<response>
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData>
<domain:infData>
<domain:name>pruebas.eu</domain:name>
<domain:roid>5767282-EURID</domain:roid>
<domain:status s="ok"/>
<domain:registrant>c10470138</domain:registrant>
<domain:contact type="billing">c887112</domain:contact>
<domain:contact type="onsite">c10470137</domain:contact>
<domain:ns>
<domain:hostAttr>
<domain:hostName>dns1.loquemedelagana.com</domain:hostName>
</domain:hostAttr>
<domain:hostAttr>
<domain:hostName>dns2.loquemedelagana.com</domain:hostName>
</domain:hostAttr>
</domain:ns>
<domain:clID>t000657</domain:clID>
<domain:crID>t000657</domain:crID>
<domain:crDate>2010-06-01T15:12:33.000Z</domain:crDate>
<domain:upID>t000657</domain:upID>
<domain:upDate>2010-06-01T15:12:33.000Z</domain:upDate>
<domain:exDate>2012-06-30T21:59:59.999Z</domain:exDate>
</domain:infData>
</resData>
<extension>
<extendedInfo:infData>
<extendedInfo:onhold>false</extendedInfo:onhold>
<extendedInfo:quarantined>false</extendedInfo:quarantined>
</extendedInfo:infData>
</extension>
<trID>
<svTRID>eurid-0</svTRID>
</trID>
</response>
</epp>
Por ejemplo <domain:contact>
Resultado:
Código HTML:
Array
(
[epp] => Array
(
[0] =>
[response] => Array
(
[0] =>
[result] => Array
(
[0] =>
[msg] => Command completed successfully
[@code] => 1000
)
[resData] => Array
(
[0] =>
[domain:infData] => Array
(
[0] =>
[domain:name] => pruebas.eu
[domain:roid] => 5767282-EURID
[domain:status] => Array
(
[@s] => ok
)
[domain:registrant] => c10470138
------------------>[domain:contact] => Array
(
[0] => c10470137
[@type] => onsite
)
[domain:ns] => Array
(
[0] =>
[domain:hostAttr] => Array
(
[0] =>
[domain:hostName] => dns2.loquemedelagana.com
)
)
[domain:clID] => t000657
[domain:crID] => t000657
[domain:crDate] => 2010-06-01T15:12:33.000Z
[domain:upID] => t000657
[domain:upDate] => 2010-06-01T15:12:33.000Z
[domain:exDate] => 2012-06-30T21:59:59.999Z
)
)
[extension] => Array
(
[0] =>
[extendedInfo:infData] => Array
(
[0] =>
[extendedInfo:onhold] => false
[extendedInfo:quarantined] => false
)
)
[trID] => Array
(
[0] =>
[svTRID] => eurid-0
)
)
[@xmlns] => http://www.eurid.eu/xml/epp/epp-1.0
)
)
Gracias.
SOLUCIÓN: quitar los : de las etiquetas. Pasa lo mismo que con simplexml.
Yo uso este código:
Código PHP:
//Arreglo de xml
$xml=preg_replace('|<([/\w]+)(:)|m','<$1',$xml);
$xml=preg_replace('|(\w+)(:)(\w+=\")|m','$1$3',$xml);