parsear - string to xml javascript
Análisis jQuery XML con espacios de nombres (20)
Soy nuevo en jQuery y me gustaría analizar un documento xml.
Puedo analizar XML regularmente 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 la <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 no tuve suerte. ¿Algunas ideas? Gracias.
A partir 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")
- Chrome 44.0.2403.89m:
.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.
Poniendo todo junto, la siguiente sintaxis funciona en todos los navegadores mencionados anteriormente: .find("row,z//:row")
Alternativamente, puede usar fast-xml-parser en su proyecto y convertir los datos XML en objetos JS / JSON. Entonces puede usarlo como propiedad del 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.
Aunque la respuesta anterior parece ser correcta, no funciona en navegadores webkit (Safari, Chrome). Una mejor solución, creo, sería:
.find("[nodeName=z:myRow, myRow]")
Como se mencionó anteriormente, hay problemas con la solución anterior con los navegadores / versiones actuales de jQuery: el complemento sugerido tampoco funciona por completo debido a problemas de casos ( 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;
});
};
Ejemplo de uso:
$.findNS($(xml), ''x:row'');
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í: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/
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 una gran cantidad de investigaciones y pruebas.
parentNode.getElementsByTagNameNS("*", "name");
Eso funcionará para recuperar el siguiente nodo: <prefix:name>
. Como puede ver, el prefijo o espacio de nombres se omite y coincidirá con los elementos con espacios de nombres distintos, siempre que el nombre de la etiqueta sea el name
. 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 un descanso, encontré una solución alternativa :) Esta función devuelve el primer nodo que coincide con un nombre de nodo 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 eso ayude!
Entiendo.
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 escaparse y funciona en todos los navegadores "modernos":
.find("[nodeName=z:row]")
Hay un plugin jquery-xmlns para jQuery para trabajar con espacios de nombres en selectores.
He pasado varias horas en esta lectura sobre complementos y todo tipo de soluciones sin suerte.
ArnisAndy publicó un enlace a una discusión 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 robar un feed de WordPress donde el contenido se llama <content: encoded> y esto es lo que funcionó para mí:
content: $this.find("content//:encoded, encoded").text()
Mi solución (porque uso un proxy Php) es reemplazar: namespace por _ ... así que no hay más problemas de espacio de nombres ;-)
Mantenlo simple !
Ninguna de las soluciones anteriores funciona tan bien. Encontré esto y me han mejorado para 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'');
No he visto ninguna documentación sobre el uso de JQuery para analizar XML. JQuery normalmente usa el dom del navegador para explorar un documento HTML, no creo que lea el html en sí.
Probablemente deberías mirar el manejo XML integrado en JavaScript.
http://www.webreference.com/programming/javascript/definitive2/
Para los navegadores Webkit, puede dejar fuera de los dos puntos. Entonces, para encontrar <media:content>
en una fuente RSS, por ejemplo, puede hacer esto:
$(this).find("content");
Respuesta original: jQuery XML analizando cómo obtener el atributo de elemento
Aquí hay un ejemplo de cómo obtener el valor de Chrome correctamente.
item.description = jQuery(this).find("[nodeName=itunes//:summary]").eq(0).text();
Si está utilizando jquery 1.5, deberá agregar comillas alrededor del valor del atributo selector de nodo para que funcione:
.find(''[nodeName="z:row"]'')
Solución encontrada en el comentario: Análisis XML con espacios de nombres usando jQuery $ (). Find
Usando la segunda mitad del nombre del nodo después de los dos puntos funcionó para mí. Usé .find ("lat") en lugar de .find ("geo /: lat") y funcionó para mí.
Mi configuración:
- Chrome 42
- jQuery 2.1.3
Ejemplo de XML (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
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. Vea estos enlaces para más información:
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 consistía en leer y analizar un archivo EXCEL a través de Sharepoint EXCEL REST API. La respuesta XML contiene etiquetas con el espacio de nombres "x:".
Decidí reemplazar el espacio de nombres en el XML por una cadena vacía. Funciona de esta manera: 1. Obtenga el nodo de interés de la respuesta XML 2. Convierta el nodo seleccionado Respuesta XML (Documento) a la Cadena 2. Reemplace el espacio de nombres por la cadena vacía 3. Convierta la cadena de nuevo a 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
contenido: $this.find("content//:encoded, encoded").text()
es la solución perfecta ...
jQuery 1.7 no funciona con lo siguiente:
$(xml).find("[nodeName=a:IndexField2]")
Una solución que conseguí trabajar en Chrome, Firefox e IE es usar selectores que funcionan en IE Y selectores que funcionan en Chrome, basados 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 de espacio de nombres. No probé esto en Safari, pero debería funcionar porque funciona en Chrome.