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 es el <z:row>
.
Hasta ahora, he estado usando:
$.get(xmlPath, {}, function(xml) {
$("rs:data", xml).find("z:row").each(function(i) {
alert("found zrow");
});
}, "xml");
realmente sin suerte. ¿Algunas ideas?
javascript
jquery
xml
namespaces
xsd
Brian Liang
fuente
fuente
Respuestas:
Lo tengo.
Resulta que requiere
\\
escapar del colon.$.get(xmlPath, {}, function(xml) { $("rs\\:data", xml).find("z\\:row").each(function(i) { alert("found zrow"); }); }, "xml");
Como señaló Rich:
La mejor solución no requiere escapar y funciona en todos los navegadores "modernos":
.find("[nodeName=z:row]")
fuente
$('[nodeName=rs:data]', xml).find('[nodeName=z:row]')
- funciona con 1.3.2 en WebKit (donde el método de dos puntos de escape aparentemente no lo hace)$('[nodeName=rs:data],data')
rs
,dt
o nos
son realmente los espacios de nombres. Los espacios de nombres son los URN en la parte superior del archivo. Los prefijos son solo alias elegidos por el autor del documento para que sea breve. Se podría crear el mismo documento, que coincida con los mismos espacios de nombres, con prefijos totalmente diferentes. Animo a todos a buscar API que comprendan los espacios de nombres en lugar de asumir prefijos en sus consultas. Por ejemplo, en la API DOM del navegador puede utilizargetElementByTagNameNS()
ygetAttributeNS()
.He pasado varias horas leyendo sobre complementos 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 ) usando jQuery (v1.7.2).
Estoy tratando de raspar un feed de WordPress donde el contenido se llama <contenido: codificado> y esto es lo que funcionó para mí:
content: $this.find("content\\:encoded, encoded").text()
fuente
.each()
bucle de repetición deitem
elementos:$('dc\\:creator, creator', this).text()
. Sin embargo, no estoy seguro de por qué, creator
se necesitaba el extra ydc\\:creator
no solo funcionó.Si está utilizando jquery 1.5, tendrá que agregar comillas alrededor del valor del atributo del selector de nodo para que funcione:
.find('[nodeName="z:row"]')
fuente
Aunque la respuesta anterior parece ser correcta, no funciona en los navegadores webkit (Safari, Chrome). Creo que una mejor solución sería:
.find("[nodeName=z:myRow, myRow]")
fuente
$('[nodeName=rs:data],data')
En caso de que alguien necesite hacer esto sin jQuery , solo con Javascript normal, y para Google Chrome (webkit) , esta es la única forma que encontré para que funcione después de mucha investigación y pruebas.
Eso va a trabajar para recuperar el nodo siguiente:
<prefix:name>
. Como puede ver, se omite el prefijo o el espacio de nombres, y coincidirá con elementos con diferentes espacios de nombres siempre que el nombre de la etiqueta seaname
. Pero espero que esto no sea 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 dormir un poco, encontré una solución que funciona :) Esta función devuelve el primer nodo que coincide con un completo
nodeName
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 eso ayude!
fuente
Ninguna de las soluciones anteriores funciona tan bien. Encontré esto y se ha mejorado la velocidad. solo agrega 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/
fuente
El "\\" escapar 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í: Mejora del rendimiento de búsqueda de nodos XML de Javascript
fuente
Vale la pena señalar que a partir de jQuery 1.7 hubo problemas con algunas de las soluciones para encontrar elementos con espacios de nombres. Consulte estos enlaces para obtener más información:
fuente
Solución encontrada en el comentario: analizar XML con espacios de nombres usando jQuery $ (). Find
Mi configuración:
XML de muestra (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
fuente
jQuery 1.7 no funciona con lo siguiente:
$(xml).find("[nodeName=a:IndexField2]")
Una solución que pude trabajar en Chrome, Firefox e IE es usar 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 que usan 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 espacios de nombres. No lo he probado en Safari, pero debería funcionar porque funciona en Chrome.
fuente
Mi solución (porque uso un proxy Php) es reemplazar: espacio de nombres por _ ... así que no más problemas de espacio de nombres ;-)
Mantenlo simple !
fuente
Respuesta original: jQuery XML analizando cómo obtener el atributo del elemento
A continuación, se muestra un ejemplo de cómo obtener correctamente el valor en Chrome.
item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text();
fuente
A principios de 2016, para mí, la siguiente sintaxis funciona con jQuery 1.12.0:
.find("z\\:row")
.find("z\\:row")
.find("row")
La sintaxis
.find("[nodeName=z:row]")
no funciona en ninguno de los navegadores mencionados anteriormente. No encontré forma de aplicar un espacio de nombres en Chrome.Poniéndolo todo junto, la siguiente sintaxis funciona en todos los navegadores mencionados anteriormente:
.find("row,z\\:row")
fuente
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 mayúsculas y minúsculas (
nodeName
, como propiedad, a veces está en mayúsculas). Entonces, 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; }); };
Uso de ejemplo:
$.findNS($(xml), 'x:row');
fuente
contenido:
$this.find("content\\:encoded, encoded").text()
es la solución perfecta ...
fuente
Hay un complemento jquery-xmlns para que jQuery funcione con espacios de nombres en los selectores.
fuente
No he visto ninguna documentación sobre el uso de JQuery para analizar XML. JQuery generalmente usa el dom del navegador para navegar por un documento HTML, no creo que lea el html en sí.
Probablemente debería mirar el manejo XML integrado en JavaScript.
http://www.webreference.com/programming/javascript/definitive2/
fuente
responseXML
propiedad delXMLHttpRequest
objeto integrado , que de hecho es un documento XML. Sin embargo, jQuery (hasta la 1.5, cuandoparseXML
se introdujo) no tenía forma de analizar XML, por lo que Chris tenía razón.simplemente reemplazó el espacio de nombres por una cadena vacía. Funciona bien para mi. Solución probada en todos los navegadores: Firefox, IE, Chrome
Mi tarea era leer y analizar un archivo 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. Saque el nodo de interés de la respuesta XML 2. Convierta el nodo XML-Response (Documento) en una cadena 2. Reemplace el espacio de nombres por una cadena vacía 3. Convierta la cadena de nuevo a un documento XML
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
fuente
Alternativamente, puede usar fast-xml-parser en su proyecto y convertir los datos XML en un objeto JS / JSON. Entonces puedes usarlo como propiedad de objeto. No usa JQuery u otras bibliotecas, pero 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 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.
fuente
Para los navegadores Webkit, puede dejar los dos puntos. Entonces, para buscar
<media:content>
en una fuente RSS, por ejemplo, puede hacer esto:$(this).find("content");
fuente