解析"非标准"用Javascript的XML?

时间:2014-08-04 17:51:07

标签: javascript xml parsing

下午好,

我正在尝试使用严格的Javascript解析XML文件(我宁愿不使用诸如jQuery之类的添加,因为此代码所在的模块中存在内存限制)。 XML文件由我在装配线控制器中的控制系统中的模块填充,因此我认为格式与典型的XML文件略有不同。我可以正确加载文件(我使用警报来查看原始文本输出,它是正确的),但我无法加载标记的值。加载的XML文件的一部分如下:

<tag name = "Parts_Built_Buffer[490].DateTime" valueType="cip:dt_STRINGI" path="1,0" access="read" display="String">
    <value xsi:type="cip:dt_STRINGI">20140804110319</value>
</tag>

它继续为500个这样的标签...由于模块要求的性质,每个标签都有一个唯一的名称,所以我想循环遍历所有标签以获取值并构建一个表。为此我的代码(减去循环部分,因为我需要在运行(加载所有值)之前爬行(加载1值))是:

var builtDataView_url = "/user/system/dataviews/Parts_Built_Buffer.xml";

    var getDataView = new XMLHttpRequest();
    getDataView.open("GET", builtDataView_url, false);
    getDataView.send();
    var builtXML = getDataView.responseXML;
    alert("response is " + getDataView.responseText)

    var job0 = builtXML.getElementsByTagName("/tag[Name='Parts_Built_Buffer[0].DateTime']/value")[0];
    alert("job0 is " + job0)

在第一个警报中,我得到了XML的文本视图,它看起来像预期的那样。但是,对于job0我得到它是未定义的(如果我警告job0.length我得到0)。我需要这个在Chrome和IE中都能使用。任何建议将不胜感激。

编辑: 我今天在控制台玩了一些(我昨天和今天早上没时间用完了)返回的数据。我对javascript很新,我自学(即谷歌)。控制台对话框如下所示,返回的XML不是使用parts_built ...标记对value标签进行分组。由于我是新手,如果函数调用没有意义,请不要取笑我尝试读取数据,请...

data.getElementsByTagName("*")
HTMLCollection[101]
data.getElementsByTagName("*")[0]
<view xmlns:xsi=​"http:​/​/​www.w3.org/​2001/​XMLSchema-instance" xmlns=​"http:​/​/​    www.rockwellautomation.com/​technologies/​data_access/​data_views/​1.0/​" xmlns:cip=​"http:​/​/​www.rockwellautomation.com/​technologies/​data_access/​data_types/​1.0/​" xsi:schemaLocation=​"http:​/​/​www.rockwellautomation.com/​technologies/​data_access/​data_views/​1.0/​ /​schema/​  dataview.xsd" name=​"EWEB_Data" description>​…​</view>​
data.getElementsByTagName("*")[1]
<tag name=​"Parts_Built_Buffer[490]​.DateTime" valueType=​"cip:​dt_STRINGI" path=​"1,0"    access=​"read" display=​"String">​
<value xsi:type=​"cip:​dt_STRINGI">​20140805111641​</value>​
</tag>​
data.getElementsByTagName("*")[1].value
undefined
data.getElementsByTagName("*")[2]
<value xsi:type=​"cip:​dt_STRINGI">​20140805111641​</value>​
data.getElementsByTagName("*")[3]
<tag name=​"Parts_Built_Buffer[490]​.VIN" valueType=​"cip:​dt_STRINGI" path=​"1,0" access=​    "read" display=​"String">​…​</tag>​
data.getElementsByTagName("*")[4]
<value xsi:type=​"cip:​dt_STRINGI">​</value>​
data.getElementsByTagName("*")[5]
<tag name=​"Parts_Built_Buffer[490]​.SerNum" valueType=​"cip:​dt_STRINGI" path=​"1,0"     access=​"read" display=​"String">​
<value xsi:type=​"cip:​dt_STRINGI">​643Y037S14217​</value>​
</tag>​
data.getElementsByTagName("*")[6]
<value xsi:type=​"cip:​dt_STRINGI">​643Y037S14217​</value>​
data.getElementsByTagName("*")[5].getElementsByTagName("*")
[
<value xsi:type=​"cip:​dt_STRINGI">​643Y037S14217​</value>​
]
data.getElementsByTagName("tag name*")[5].getElementsByTagName("*")
TypeError: Cannot read property 'getElementsByTagName' of undefined
data.getElementsByTagName("Parts_Built_Buffer*")[5].getElementsByTagName("*")
TypeError: Cannot read property 'getElementsByTagName' of undefined

此代码将生成值(请记住,我只关心偶数标记索引,因为它们保存值...     data.getElementsByTagName( “*”)[6] .textContent

这看起来很笨重但是任何建议仍然会受到赞赏......至少看起来我不必从文本输出开始并通过长文本字符串解析......

1 个答案:

答案 0 :(得分:0)

您可以使用标准DOM属性:childNodesfirstChildnextSibling

因此,我会导航到包含所有标记的节点,然后我会在for上使用childNodes循环。类似的东西:

var main_node = something;
var table = {};
for (var i = 0; i < main_node.childNodes.length; i++) {
    var node = main_node.childNodes[i];
    if (node.nodeType == 1) {
        // Insert your code here.
        var name = node.getAttribute('name');
        var value = writeYourFunctionToExtractValueFromNode(node);
        table[name] = value;
    }
}

// After the pre-processing step above, you can just use:
alert(table['Parts_Built_Foobar']);

nodeType的检查是跳过评论,空格和其他不相关的节点。

我在这里提到的所有内容都只是标准的DOM,几乎可以在任何地方使用(包括JavaScript以外的语言)。