2010-12-08 12 views
9

Hola, ¿cuál es la mejor manera de contar la cantidad de elementos en un archivo XML? En mi caso, quiero contar el número de etiquetas XML con el nombre "OfferName" dentro de la etiqueta "OfferNameList".php count xml elements

El XML siguiente está contenido en una variable php $ ofrece

$offers = '<OfferNameList> 
    <OfferName>...</OfferName> 
    <OfferName>...</OfferName> 
    <OfferName>...</OfferName> 
    ... 
</OfferNameList>'; 

Gracias por la ayuda

Respuesta

21
Con

DOM se puede utilizar

$dom->getElementsByTagName('OfferName')->length; 

para contar todos los elementos sólo OfferName. length is an attribute of DOMNodeList.

Contar todos los elementos dentro de una OfferName OfferNameList, puede utilizar DOMXPath::evaluate

$xpath->evaluate('count(//OfferNameList/OfferName'); 

Tenga en cuenta que dentro de es algo inexacto aquí como la consulta XPath sólo considerará hijos directos. Ajuste su pregunta si necesita elementos OfferName en cualquier lugar debajo de un elemento OfferNameList.

También tenga en cuenta que // consultará en cualquier lugar del documento, lo que puede ser menos eficiente para documentos grandes. Si sabe que los elementos de OfferNameList se encuentran en una determinada posición solo en su XML, use una ruta directa. ejemplo


completa de trabajo (run on codepad):

$xml = <<< XML 
<root> 
    <NotOfferNameList> 
     <OfferName>...</OfferName> 
     <OfferName>...</OfferName> 
     <OfferName>...</OfferName> 
    </NotOfferNameList> 
    <OfferNameList> 
     <OfferName>...</OfferName> 
     <OfferName>...</OfferName> 
     <OfferName>...</OfferName> 
    </OfferNameList>; 
</root> 
XML; 

$dom = new DOMDocument; 
$dom->loadXml($xml); 

// count all OfferName elements 
echo $dom->getElementsByTagName('OfferName')->length, PHP_EOL; // 6 

// count all OfferNameList/OfferName elements 
$xp = new DOMXPath($dom); 
echo $xp->evaluate('count(//OfferNameList/OfferName)'); // 3 
+0

¡Gracias por el ejemplo del código! Por favor, podría publicar esto en su pregunta para que los futuros lectores puedan ver esto en caso de que el enlace de arriba desaparezca. – Martin

+0

@Martin, de nada. ¡Hecho! – Gordon

+2

¡Gracias! Bien respondido y muy apreciado! – Martin

3

eighter utiliza simplexml: http://www.php.net/manual/de/simplexmlelement.count.php

<?php 
$xml = <<<EOF 
<OfferNameList> 
<OfferName> 
    <child/> 
    <child/> 
</OfferName> 
<OfferName> 
    <child/> 
    <child/> 
    <child/> 
</OfferName> 
</OfferNameList> 
EOF; 

$elem = new SimpleXMLElement($xml); 
printf("%d offers.\n", $elem->OfferNameList->count()); 

?> 

o lo hace con DOM

$domobj->getElementsByTagName('OfferName')->length; 
+1

Esto supone que OfferNameList solo tiene hijos OfferName y es exactamente la razón por la que no estoy usando SimpleXml. Te obliga a hacer suposiciones sobre el marcado. – Gordon

3

Usted puede utilizar la función de PHP substr_count

<?php 
    $tag_count = substr_count($offers, "<OfferName>"); 
?> 

Es posible que necesite extraer el contenido de las etiquetas mediante el uso de una expresión regular primero.

Si usted es el autor del archivo XML, que también podría simplemente incrustar el recuento como un atributo de la etiqueta OfferNameList, tales como ....

Por último, si usted necesita para analizar el archivo XML, Le sugiero encarecidamente que obtenga un analizador XML adecuado (DOM Parser contará las etiquetas internas por usted, suponiendo que su XML no sea demasiado grande) pero también podrá hacerlo con una implementación de analizador SAX.

1

la adición a solución dada por @Gordon (que funciona perfectamente bien para la pregunta hecha), no es mencionado y para la gente que no es muy obvio para: Es posible utilizar evaluate Si desea contar OfferName de algún XML como: `

<OfferNameList> 
<OfferName> 
    <child/> 
    <child/> 
</OfferName> 
<OfferName> 
    <child/> 
    <child/> 
    <child/> 
</OfferName> 
</OfferNameList> 

<OfferNameList> 
<OfferName> 
    <child/> 
    <child/> 
</OfferName> 
</OfferNameList> 

Uno puede usar

echo $xp->evaluate('count(//OfferNameList[1]/OfferName)'); a contar desde PRIMERA OfferNameList y

echo $xp->evaluate('count(//OfferNameList[2]/OfferName)'); a contar desde SEGUNDO.

P.S .:

Estoy publicar esta respuesta aquí porque quería lograr algo parecido a lo que acaba de aparecer y me encontré con este post en google'ing!

Seondly, utilizamos 1 y 2 para acceder a los PRIMERA y SEGUNDO listas y NO 0 y 1. novatos como yo puede no saber esto.