2011-10-27 26 views
5

He estado revisando todo mi código anterior y tratando de optimizarlo. Algo Hace poco se topó con y que ha conseguido me difuminados está tratando de encontrar una solución para este XPath:Encontrar elemento específico basado en un atributo

function findit($search) { 
    $i=0; 
    foreach($xml as $page) { //loop to find specific $element based on $attribute 
     if($page['src']==$search) { return $i; } 
     $i++; 
    } 
} 

necesita volver $i para que pueda ser utilizado como referencia al elemento en el XML más adelante.

Parece que debería ser posible, y he encontrado algunas cadenas de xpath que parecen que deberían funcionar, pero no es así. Por lo general, se refieren al preceding-children y los cuentan a través de la función xpath(), pero ya no puedo encontrar las fuentes originales y no sé cómo traducir eso a una cadena PHP xpath.

¿Esto es posible? ¿O es mejor/más rápido/eficiente que lo que ya tengo? Sugerencias/Soluciones?

EDIT: Para la solución

Ejemplo de mi XML del archivo Tandu

<range> 
    <page src="attribute1" /> 
    <page src="attribute2" /> 
    etc... 
    <page src="attribut20" /> 
</range> 

En mi función actual de PHP, $i siempre devuelve 0 pero debe regresar cualquier posición $search se encuentra en. Editado por lo que ya no necesita convertir simplexml.

function findit($search) { 
    $dom=new DOMDocument('1.0'); 
    $dom->load($file); 
    $xpath=new DOMXPath($dom); 
    $i=$xpath->evaluate("count(/range/page[@src='$search']/preceding-sibling::*)"); 
    die($dom->saveXML()); 
} 

Respuesta

3

PHP tiene al menos dos (que yo sepa) métodos para el manejo de XPath: la biblioteca DOMXPath, que trabaja con DOMDocument y SimpleXML, que tiene su propio método xpath(). Si desea evaluar expresiones reales (como obtener el i en su ejemplo), debe usar DOMXPath::evaluate(). SimpleXML::xpath() sólo devolverá una lista de nodos (como voluntad DOMXPath::query(). También hay métodos xpath_ en php, pero estos parecen ser versiones funcionales de los otros métodos y todavía requieren DOM objetos de nodo de contexto.

No estoy seguro de lo que el xml en su ejemplo anterior es, pero el ejemplo siguiente se utiliza DOMXPath. que yo sepa, no existe una forma sencilla de convertir a SimpleXMLDOMDocument. Usted sólo tiene que cargar el código XML por separado.

$xml = <<<XML 
    <root> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="two" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
     <child attribute="one" /> 
    </root> 
XML; 
$dom = new DOMDocument; 
$dom->loadXML($xml); 
//DOMXPath requires DOMDocument in its constructor 
$xpath = new DOMXPath($dom); 
//evaluate will return types .. we are expecting an int, not a DOMNodeList 
//Look for a child node of root named "child" with attribute="two" 
//Count all its preceding siblings. 
$i = $xpath->evaluate('count(/root/child[@attribute="two"]/preceding-sibling::*)'); 
+0

estado usando simplexml durante tanto tiempo me había olvidado de su hermano mayor dom! – mseancole

+0

* No me di cuenta de que ingresar agregaría comentarios en lugar de pasar a la siguiente línea XD Mi XML es, por supuesto, simplexml. Esto es lo que tengo, no estoy seguro si es la manera más elegante, pero aún no puedo hacer que funcione :( Agregué el código en la publicación original porque no pude formatearlo aquí correctamente :( – mseancole

+0

@showerhead puedo vea su xml? Tenga en cuenta que "raíz" y "hijo" son los nombres de los nodos.Por ejemplo, si tiene '' en su lugar, reemplazaría "raíz" por "padre" y "hijo" por "hijo" en mi ejemplo. Veo que estás usando "niño" en el ejemplo de tu pregunta. –

0

uso una sola expresión XPath, por lo que no necesita iterar el resultado:

elementWithSomeName[@attribute = 'someNeededValue'] 

o (en el caso de "atributo es un nombre de un elemento):

elementWithSomeName[attribute = 'someNeededValue'] 
+0

sí, he llegado tan lejos, estaba iterando para poder encontrar su posición específica en el xml, por lo tanto $ i. Gracias de cualquier forma – mseancole

Cuestiones relacionadas