Javascript 正则表达式将XML转换为JSON

Javascript 正则表达式将XML转换为JSON,javascript,xml,regex,json,parse-platform,Javascript,Xml,Regex,Json,Parse Platform,这是前一个问题的延续: 请不要投反对票,因为你不相信正则表达式是正确的选择。这是我必须处理的问题。如果您有其他解决方法,请告诉我。但它必须在Parse.com的云代码上运行 原始XML: <?xml version="1.0" encoding="UTF-8" ?><api><products total-matched="1618" records-returned="1" page-number="1"><product><ad-id&

这是前一个问题的延续:

请不要投反对票,因为你不相信正则表达式是正确的选择。这是我必须处理的问题。如果您有其他解决方法,请告诉我。但它必须在Parse.com的云代码上运行

原始XML:

<?xml version="1.0" encoding="UTF-8" ?><api><products total-matched="1618" records-returned="1" page-number="1"><product><ad-id>1234</ad-id><supplier-name>Window World</supplier-name><supplier-category>3703703</supplier-category><buy-url>http://website.com</buy-url><currency>USD</currency><description>Window</description><image-url>http://website.com/windowa/80x80.jpg</image-url><in-stock>yes</in-stock><manufacturer-name>Window World</manufacturer-name><name>Half Pain Glass</name><price>31.95</price><retail-price>87.60</retail-price><sale-price>29.95</sale-price><sku>5938</sku><upc></upc></product><product><ad-id>1234</ad-id><supplier-name>Window World</supplier-name><supplier-category>3703703</supplier-category><buy-url>http://website.com</buy-url><currency>USD</currency><description>Window</description><image-url>http://website.com/windowa/80x80.jpg</image-url><in-stock>yes</in-stock><manufacturer-name>Window World</manufacturer-name><name>Half Pain Glass</name><price>31.95</price><retail-price>87.60</retail-price><sale-price>29.95</sale-price><sku>5938</sku><upc></upc></product><product><ad-id>1234</ad-id><supplier-name>Window World</supplier-name><supplier-category>3703703</supplier-category><buy-url>http://website.com</buy-url><currency>USD</currency><description>Window</description><image-url>http://website.com/windowa/80x80.jpg</image-url><in-stock>yes</in-stock><manufacturer-name>Window World</manufacturer-name><name>Half Pain Glass</name><price>31.95</price><retail-price>87.60</retail-price><sale-price>29.95</sale-price><sku>5938</sku><upc></upc></product><product><ad-id>1234</ad-id><supplier-name>Window World</supplier-name><supplier-category>3703703</supplier-category><buy-url>http://website.com</buy-url><currency>USD</currency><description>Window</description><image-url>http://website.com/windowa/80x80.jpg</image-url><in-stock>yes</in-stock><manufacturer-name>Window World</manufacturer-name><name>Half Pain Glass</name><price>31.95</price><retail-price>87.60</retail-price><sale-price>29.95</sale-price><sku>5938</sku><upc></upc></product></products></api>

我所知道的最后一个问题是,这不会使重复项成为JSON数组。有没有办法解决这个问题

好吧,请注意,这是一个快速解决方案,但它似乎有效。这将只添加一个数组结构,这样您的密钥就不会多次相同(但不会破坏该密钥)。
更改:

替换(/<*(\w[\w-]+\b)*>(?=.*?<\/\1\},\{)/g,“$1”:[{')。
拆分(/\},\{/)。
反向()。
连接('},{')。
替换(/<*\/*(\w[\w-]+\b)*>(?=.*?“\1:\[\{)/g,'}],'))。
拆分(/\},\{/)。
反向()。
连接('},{')。
这是一种实现阵列的尝试。
并提出:

replace(/< *(\w[\w-]+\b) *>(?=("\w[\w-]+\b)":\{.*?\},\2)(.*?)< *\/ *\1 *>/, '"$1":[$3],')
replace(/<*(\w[\w-]+\b)*>(?=(“\w[\w-]+\b)”:\{.*},2)(.*?<*/*\1*>,“$1:[$3],”)

请注意,我几乎使用了他的匹配方式。这至少对您来说是可行的。

使用正则表达式是一种有趣的方法,它确实比使用节点列表快一点。但是,当速度不是决定因素时(如OP的应用程序)那么,这不是将xml转换为js的最佳方式。正则表达式代码大约压缩了1kb。对于相同的字节数,您可以构建一个相当健壮且可重用的转换器……它甚至可以处理不同浏览器中的xml名称空间

我编写了以下代码(压缩),它可以很好地处理OP的XML数据

    var xml2js=function(m,p){var f=1,o=2,d=3,n=4,j=7,c=8,h=9,l,b,a,k={},g=[];if(!p){p={}}if(typeof p=="string"){p={find:p}}p.xmlns=p.xmlns||"*";if(p.parse!="function"){p.parse=e}function e(i){return i.split(":").pop().replace(/^ows_/,"").replace(/[^a-z,A-Z,0-9]/g,"")}switch(m.nodeType){case h:a=(!p.find)?m.childNodes:(m.getElementsByTagNameNS)?m.getElementsByTagNameNS(p.xmlns,p.find.split(":").pop()):m.getElementsByTagName(p.find);for(l=0;l<a.length;l++){k=xml2js(a[l]);if(k){g.push(k)}}k=(g.length&&g.length==1)?g[0]:g;break;case f:if(m.attributes.length==0&&m.childNodes.length==1&&m.childNodes.item(0).nodeValue){k=m.childNodes.item(0).nodeValue}for(l=0;l<m.attributes.length;l++){b=p.parse(m.attributes.item(l).nodeName);k[b]=m.attributes.item(l).nodeValue}for(l=0;l<m.childNodes.length;l++){if(m.childNodes.item(l).nodeType!=d){b=p.parse(m.childNodes.item(l).nodeName);if(typeof k[b]=="undefined"){k[b]=xml2js(m.childNodes.item(l))}else{if(typeof k[b].push=="undefined"){k[b]=[k[b]]}k[b].push(xml2js(m.childNodes.item(l)))}}}break;case n:k="<![CDATA["+m.nodeValue+"]]>";break;case d:k=m.nodeValue;break;case c:k="";break;default:k=null}return k};
输出:

"api": {
    "page-number": "1",
    "records-returned": "1",
    "total-matched": "1618",
    "products": {
        "product": {
            "ad-id": "1234",
            "supplier-name": "Window World",
            "supplier-category": "3703703",
            "buy-url": "http://website.com",
            "currency": "USD",
            "description": "Window",
            "image-url": "http://website.com/windowa/80x80.jpg",
            "in-stock": "yes",
            "manufacturer-name": "Window World",
            "name": "Half Pain Glass",
            "price": "31.95",
            "retail-price": "87.60",
            "sale-price": "29.95",
            "sku": "5938",
            "upc": ""
        },
        "product": {
            "ad-id": "1234",
            "supplier-name": "Window World",
            "supplier-category": "3703703",
            "buy-url": "http://website.com",
            "currency": "USD",
            "description": "Window",
            "image-url": "http://website.com/windowa/80x80.jpg",
            "in-stock": "yes",
            "manufacturer-name": "Window World",
            "name": "Half Pain Glass",
            "price": "31.95",
            "retail-price": "87.60",
            "sale-price": "29.95",
            "sku": "5938",
            "upc": ""
        },
        "product": {
            "ad-id": "1234",
            "supplier-name": "Window World",
            "supplier-category": "3703703",
            "buy-url": "http://website.com",
            "currency": "USD",
            "description": "Window",
            "image-url": "http://website.com/windowa/80x80.jpg",
            "in-stock": "yes",
            "manufacturer-name": "Window World",
            "name": "Half Pain Glass",
            "price": "31.95",
            "retail-price": "87.60",
            "sale-price": "29.95",
            "sku": "5938",
            "upc": ""
        },
        "product": {
            "ad-id": "1234",
            "supplier-name": "Window World",
            "supplier-category": "3703703",
            "buy-url": "http://website.com",
            "currency": "USD",
            "description": "Window",
            "image-url": "http://website.com/windowa/80x80.jpg",
            "in-stock": "yes",
            "manufacturer-name": "Window World",
            "name": "Half Pain Glass",
            "price": "31.95",
            "retail-price": "87.60",
            "sale-price": "29.95",
            "sku": "5938",
            "upc": ""
        }
    }
}
    {
    "pagenumber": "1",
    "recordsreturned": "1",
    "totalmatched": "1618",
     "product": [
      {
        "adid": "1234",
        "suppliername": "Window World",
        "suppliercategory": "3703703",
         "buyurl": "http://website.com",


         etc...

如果您可以从正则表达式转换到Javascript,那么请看一看。我在一开始就尝试过,但在Parse.com的云上不起作用。我用这个正则表达式做了进一步的工作。谢谢,我也尝试过了,不起作用(在Parse.com的API发生变化时,你不可能有力量去接触这段代码。也不可能有任何人想要调试这段代码。你最好先将xml转换为javascript对象,然后再将对象转换为JSON。至少会有可调试的步骤。我必须添加.replace(/],\s*?“*?:*[/g,,”)到你做了什么,让它通过JSON格式化程序jsonformatter.curiousconcept.com,然后把整个东西用{}大括号括起来。但是现在一切似乎都好了。再次感谢你的帮助!(产品出现了多次)不过,整个东西还是有问题,如果我能想出更好的东西,我会告诉你的。
    var xml2js=function(m,p){var f=1,o=2,d=3,n=4,j=7,c=8,h=9,l,b,a,k={},g=[];if(!p){p={}}if(typeof p=="string"){p={find:p}}p.xmlns=p.xmlns||"*";if(p.parse!="function"){p.parse=e}function e(i){return i.split(":").pop().replace(/^ows_/,"").replace(/[^a-z,A-Z,0-9]/g,"")}switch(m.nodeType){case h:a=(!p.find)?m.childNodes:(m.getElementsByTagNameNS)?m.getElementsByTagNameNS(p.xmlns,p.find.split(":").pop()):m.getElementsByTagName(p.find);for(l=0;l<a.length;l++){k=xml2js(a[l]);if(k){g.push(k)}}k=(g.length&&g.length==1)?g[0]:g;break;case f:if(m.attributes.length==0&&m.childNodes.length==1&&m.childNodes.item(0).nodeValue){k=m.childNodes.item(0).nodeValue}for(l=0;l<m.attributes.length;l++){b=p.parse(m.attributes.item(l).nodeName);k[b]=m.attributes.item(l).nodeValue}for(l=0;l<m.childNodes.length;l++){if(m.childNodes.item(l).nodeType!=d){b=p.parse(m.childNodes.item(l).nodeName);if(typeof k[b]=="undefined"){k[b]=xml2js(m.childNodes.item(l))}else{if(typeof k[b].push=="undefined"){k[b]=[k[b]]}k[b].push(xml2js(m.childNodes.item(l)))}}}break;case n:k="<![CDATA["+m.nodeValue+"]]>";break;case d:k=m.nodeValue;break;case c:k="";break;default:k=null}return k};
    function test( ) {
        var nodeName = 'products'; // optional - any node name
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'CloudCode.xml', false);
        xhr.send();
        var js = xml2js( xhr.responseXML, nodeName );
        console.log(JSON.stringify( js, null, '\t'));
    }
    {
    "pagenumber": "1",
    "recordsreturned": "1",
    "totalmatched": "1618",
     "product": [
      {
        "adid": "1234",
        "suppliername": "Window World",
        "suppliercategory": "3703703",
         "buyurl": "http://website.com",


         etc...