Análisis XML de jQuery con espacios de nombres


Soy nuevo en jQuery y me gustaría analizar un documento xml.

Puedo analizar XML normal con los espacios de nombres predeterminados pero con xml como:

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
   <s:Schema id="RowsetSchema">
     <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
       <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">
        <s:datatype dt:type="i4" dt:maxLength="4" />
      </s:AttributeType>
       <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
    </s:ElementType>
  </s:Schema>
   <rs:data>
    <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />
    <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />
    <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />
  </rs:data>
</xml>

Todo lo que realmente quiero son los <z:row> ' s.

Hasta ahora, he estado haciendo:

$.get(xmlPath, {}, function(xml) {
    $("rs:data", xml).find("z:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");

Realmente sin suerte. Alguna idea? Gracias.

Author: Matthias, 2009-05-12

20 answers

Lo tengo.

Resulta que requiere \\ para escapar del colon.

$.get(xmlPath, {}, function(xml) {
    $("rs\\:data", xml).find("z\\:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");

Como Rich señaló:

La mejor solución no requiere escapar y funciona en todos los navegadores "modernos":

.find("[nodeName=z:row]")
 129
Author: Brian Liang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-16 15:35:25

He pasado varias horas en esta lectura sobre plugins y todo tipo de soluciones sin suerte.

ArnisAndy publicó un enlace a una discusión de jQuery, donde se ofrece esta respuesta y puedo confirmar que esto funciona para mí en Chrome(v18.0), FireFox(v11.0), IE(v9.08) y Safari (v5.1.5) utilizando jQuery (v1.7.2).

Estoy tratando de raspar un feed de WordPress donde el contenido se llama y esto es lo que funcionó para mí:

content: $this.find("content\\:encoded, encoded").text()
 33
Author: Fasani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-07 20:02:36

Si está utilizando jquery 1.5 tendrá que agregar comillas alrededor del valor del atributo del selector de nodos para que funcione:

.find('[nodeName="z:row"]')
 19
Author: s0laris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-12 01:16:41

Aunque la respuesta anterior parece ser correcta, no funciona en los navegadores webkit (Safari, Chrome). Una mejor solución creo que sería:

.find("[nodeName=z:myRow, myRow]")    
 19
Author: Rich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-01 23:50:31

En caso de que alguien necesite hacer esto sin jQuery, solo con Javascript normal, y para Google Chrome (webkit), esta es la única manera que encontré para que funcione después de mucha investigación y pruebas.

parentNode.getElementsByTagNameNS("*", "name");

Que funcionará para recuperar el siguiente nodo: <prefix:name>. Como puede ver, el prefijo o espacio de nombres se omite, y coincidirá con elementos con diferentes espacios de nombres siempre que el nombre de la etiqueta sea name. Pero espero que esto no sea un un problema para ti.

Nada de esto funcionó para mí (estoy desarrollando una extensión de Google Chrome):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Editar: después de un poco de sueño, Encontré una solución de trabajo :) Esta función devuelve el primer nodo que coincide con un nodeName completo como <prefix:name>:

// Helper function for nodes names that include a prefix and a colon, such as "<yt:rating>"
function getElementByNodeName(parentNode, nodeName)
{   
    var colonIndex = nodeName.indexOf(":");
    var tag = nodeName.substr(colonIndex + 1);
    var nodes = parentNode.getElementsByTagNameNS("*", tag);
    for (var i = 0; i < nodes.length; i++)
    {
        if (nodes[i].nodeName == nodeName) return nodes[i]
    }
    return undefined;
}

Se puede modificar fácilmente en caso de que necesite devolver todos los elementos coincidentes. Espero que ayude!

 15
Author: cprcrack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-25 16:30:18

Ninguna de las soluciones anteriores funciona tan bien. Encontré esto y se ha mejorado para la velocidad. simplemente agregue esto, funcionó como un encanto:

$.fn.filterNode = function(name) {
    return this.find('*').filter(function() {
       return this.nodeName === name;
    });
};

Uso:

var ineedthatelementwiththepsuedo = $('someparentelement').filterNode('dc:creator');

Fuente: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/

 13
Author: Tj Tate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-22 16:56:01

El escape "\ \ " no es infalible y el simple

.find('[nodeName="z:row"]')

El método parece haberse roto a partir de Jquery 1.7. Pude encontrar una solución para 1.7, usando una función de filtro, aquí: Mejorando el rendimiento de Búsqueda de Nodos XML de Javascript

 9
Author: jmazella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-14 20:47:36

Vale la pena señalar que a partir de jQuery 1.7 hubo problemas con algunas de las soluciones para encontrar elementos de espacio de nombres. Consulte estos enlaces para obtener más información:

 3
Author: ArnisAndy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-26 21:23:13

Se encontró la solución en el comentario: Analizar XML con espacios de nombres usando jQuery $().buscar

Usar la segunda mitad del nombre del nodo después de los dos puntos funcionó para mí. Usado .encuentra ("lat") en lugar de .find ("geo\: lat") y funcionó para mí.


Mi configuración:

  • Cromo 42
  • jQuery 2.1.3

XML de ejemplo (fragmento de la API de contactos de Google):

<entry>
  <id>http://www.google.com/m8/feeds/contacts/mstefanow%40gmail.com/base/0</id>
  <gd:email rel="http://schemas.google.com/g/2005#other" address="[email protected]" primary="true"/>
</entry>

Código de análisis:

var xmlDoc = $.parseXML( xml );
var $xml = $( xmlDoc );
var $emailNode = $xml.find( "email" );
$("#email").html($emailNode.attr("address"));

Plnkr: http://plnkr.co/edit/l8VzyDq1NHtn5qC9zTjf?p=preview

 3
Author: Michal Stefanow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:45

JQuery 1.7 no funciona con lo siguiente:

$(xml).find("[nodeName=a:IndexField2]")

Una solución que hice llegar a trabajar en Chrome, Firefox, e IE es utilizar selectores que funcionan en IE Y selectores que funcionan en Chrome, basado en el hecho de que una forma funciona en IE y la otra en Chrome:

$(xml).find('a\\\\:IndexField2, IndexField2')

En IE, esto devuelve nodos usando el espacio de nombres (Firefox e IE requieren el espacio de nombres), y en Chrome, el selector devuelve nodos basados en el selector que no es de espacio de nombres. No he probado esto en Safari, pero debería funcionar porque está funcionando en Chrome.

 2
Author: SeattleDiver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-26 08:27:43

Mi solución (porque uso un proxy Php) es reemplazar : namespace por _ ... así que no más problemas de espacio de nombres; -)

¡Hazlo simple !

 2
Author: Thomas Decaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-09 16:25:55

Respuesta original: jQuery XML parsing cómo obtener el atributo element

Aquí hay un ejemplo de cómo obtener con éxito el valor en Chrome..

 item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text();
 2
Author: jdrefahl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:45

A principios de 2016, para mí la siguiente sintaxis funciona con jQuery 1.12.0:

  • IE 11 (11.0.9600.18204, Actualización 11.0.28, KB3134815): .find("z\\:row")
  • Firefox 44.0.2: .find("z\\:row")
  • Cromo 44.0.2403.89 m: .find("row")

La sintaxis .find("[nodeName=z:row]") no funciona en ninguno de los navegadores mencionados anteriormente. No he encontrado ninguna manera de aplicar un espacio de nombres en Chrome.

Juntando todo, la siguiente sintaxis funciona en todos los navegadores mencionados anteriormente: .find("row,z\\:row")

 2
Author: stefan.schwetschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-23 10:07:58

Como se mencionó anteriormente, hay problemas con la solución anterior con los navegadores/versiones actuales de jQuery: el complemento sugerido tampoco funciona completamente debido a problemas de caso (nodeName, como propiedad, a veces está en mayúsculas). Por lo tanto, escribí la siguiente función rápida:

$.findNS = function (o, nodeName)
{
    return o.children().filter(function ()
    {
        if (this.nodeName)
            return this.nodeName.toUpperCase() == nodeName.toUpperCase();
        else
            return false;
    });
};

Ejemplo de uso:

$.findNS($(xml), 'x:row');
 1
Author: Mike Oliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-29 01:12:58

Contenido: $this.find("content\\:encoded, encoded").text()

Es la solución perfecta...

 1
Author: MackMon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-23 10:34:19

Hay un plugin jquery-xmlns para que jQuery funcione con espacios de nombres en selectores.

 1
Author: Dima Fomin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 16:54:37

No he visto ninguna documentación sobre el uso de jQuery para analizar XML. jQuery normalmente utiliza el dom del navegador para navegar por un documento HTML, no creo que lea el html en sí.

Probablemente debería mirar el manejo de XML incorporado en JavaScript.

Http://www.webreference.com/programming/javascript/definitive2 /

 0
Author: Chris Brandsma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-12 21:59:20

Acaba de reemplazar el espacio de nombres por una cadena vacía. Funciona bien para mí. Solución probada en todos los navegadores: Firefox, IE, Chrome

Mi tarea era leer y analizar un archivo de EXCEL a través de Sharepoint EXCEL REST API. La respuesta XML contiene etiquetas con espacio de nombres" x:".

Decidí reemplazar el espacio de nombres en el XML por una cadena vacía. Funciona de esta manera: 1. Obtener el nodo de interés de la respuesta XML 2. Convertir el nodo seleccionado XML-Response (Document) a String 2. Reemplazar espacio de nombres por cadena vacía 3. Convertir cadena de nuevo a XML-Document

Vea el esquema del código aquí > >

function processXMLResponse)(xData)
{
  var xml = TOOLS.convertXMLToString("", "",$(xData).find("entry content")[0]);
  xml = xml.replace(/x:/g, "");            // replace all occurences of namespace
  xData =  TOOLS.createXMLDocument(xml);   // convert string back to XML
}

Para la conversión de XML a cadena encuentre una solución aquí: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string

 0
Author: Karl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-09 18:46:27

Alternativamente, puede usar fast-xml-parser en su proyecto y convertir los datos XML en objetos JS/JSON. Luego puede usarlo como propiedad de objeto. No utiliza jQuery u otras bibliotecas, pero va a resolver su propósito.

var xmlData = '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">'
+'   <s:Schema id="RowsetSchema">'
+'     <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">'
+'       <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">'
+'        <s:datatype dt:type="i4" dt:maxLength="4" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'    </s:ElementType>'
+'  </s:Schema>'
+'   <rs:data>'
+'    <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />'
+'    <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />'
+'    <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />'
+'  </rs:data>'
+'</xml>'

var jsObj = parser.parse(xmlData,{attrPrefix:"",ignoreTextNodeAttr: false});
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][0],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][1],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][2],null,4) + "<br>");
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/2.9.2/parser.min.js"></script>

Puede ignorar los espacios de nombres mientras analiza el objeto js/json. En este caso se puede acceder directamente como jsObj.xml.data.row.

for(var i=0; i< jsObj.xml.data.row.length; i++){
  console.log(jsObj.xml.data.row[i]);
}

Descargo de responsabilidad : He creado fast-xml-parser.

 0
Author: Amit Kumar Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 04:19:24

Para los navegadores Webkit, solo puede dejar los dos puntos. Así que para encontrar <media:content> en un feed RSS, por ejemplo, puede hacer esto:

$(this).find("content");
 -1
Author: donnapep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-18 14:02:16