如何有效地测试和解析XML中的深层价值? [英] How to efficiently test and parse a deep value in XML?

查看:157
本文介绍了如何有效地测试和解析XML中的深层价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ColdFusion 8。



我解析一个XML文档,需要得到一个深深埋在文档中的单个值。我成功地解析文档并获取我需要的值,但似乎必须有一个更有效的方法来获得相同的数据。



我没有解析了很多XML。是否必须测试存在的密钥这深刻非常典型的解析XML或我做错了什么?是否有更好的方法来编写代码?

  // PARSE SOAP响应
SoapResponse = xmlParse(httpResponse.fileContent );
//将响应节点插入到数组
ResponseNodes = xmlSearch(SoapResponse,// * [local-name()='OnlineBoothInformation']);

//通过ARRAY循环并获取每个节点
for(i = 1; i lte arrayLen(ResponseNodes); i ++){
//创建新结构以保持BOOTH DATA
BoothInfo = structNew();

//测试自定义字段以查找新展商
BoothInfo.NewExhibitor = 0; // DEFAULT NEW EXHIBITOR
if(structKeyExists(ResponseNodes [i],CustomFields)){
CustomFields = xmlParse(ResponseNodes [i] .CustomFields);
for(j = 1; j lte arrayLen(CustomFields); j = j + 1){
if(structKeyExists(ResponseNodes [i] .CustomFields [j],Field)){
Field = xmlParse(ResponseNodes [i] .CustomFields [j] .Field);
for(k = 1; k lte arrayLen(Field); k = k + 1){
if(ResponseNodes [i] .CustomFields [j] .Field [k] .XmlAttributes.Name == 新展商){
BoothInfo.NewExhibitor = 1;
}
}
}
}
}
}

我得到BoothInfo结构的其他值。他们更容易得到。

UPDATE



我可以重写代码并获取

  //新参展商
BoothInfo.NewExhibitor = 0;
if(structKeyExists(ResponseNodes [i] .CustomFields,Field)){
Fields = ResponseNodes [i] .CustomFields.Field;
for(j = 1; j lte arrayLen(Fields); j ++){
if(Fields [j] .XmlAttributes.Name ==New Exhibitor){
BoothInfo.NewExhibitor = 1;
break;
}
}
}


解决方案>

好吧,我不明白为什么你一直调用xmlParse。您可以使用它将一个字符串转换为XML节点集,但您已经有一个XML节点集。



您可以为所需的节点使用更具体的XPath规范。也许像 // * [local-name()='OnlineBoothInformation'] / CustomFields / Field [@ Name =New Exhibitor] 。然后你可以检查是否返回一个空数组。 XPath是真的具有表现力,但它需要一些习惯。注意,虽然CF通常不区分大小写,XPath是。我从您的CF复制的情况下,但是必须匹配XML中的情况下才能工作。


I am using ColdFusion 8.

I am parsing an XML document and need to get at a single value that is buried deep in the document. I am successfully parsing the document and getting the values I need, but it seems that there has to be a more efficient means to get to the same data.

I have NOT parsed much XML. Is having to test for the existence of keys this deep very typical in parsing XML or am I doing something wrong? Is there a better way to code this?

// PARSE THE SOAP RESPONSE 
SoapResponse = xmlParse(httpResponse.fileContent);
// PUT THE RESPONSE NODES INTO AN ARRAY
ResponseNodes = xmlSearch(SoapResponse, "//*[ local-name() = 'OnlineBoothInformation' ]");

// LOOP THROUGH THE ARRAY AND GET EACH NODE
for (i = 1; i lte arrayLen(ResponseNodes); i++) {
  // CREATE NEW STRUCTURE TO HOLD BOOTH DATA
  BoothInfo  = structNew();

  // TEST FOR CUSTOM FIELDS TO FIND NEW EXHIBITOR
  BoothInfo.NewExhibitor = 0; // DEFAULT NEW EXHIBITOR
    if (structKeyExists(ResponseNodes[i], "CustomFields")) {
      CustomFields = xmlParse(ResponseNodes[i].CustomFields);
      for (j = 1; j lte arrayLen(CustomFields); j=j+1) {
        if (structKeyExists(ResponseNodes[i].CustomFields[j], "Field")) {
          Field = xmlParse(ResponseNodes[i].CustomFields[j].Field);
          for (k = 1; k lte arrayLen(Field); k=k+1) {
            if (ResponseNodes[i].CustomFields[j].Field[k].XmlAttributes.Name == "New Exhibitor") {
        BoothInfo.NewExhibitor = 1;
    }
          }
        }
      }
    }
  }

I am getting other values for the BoothInfo structure. They were MUCH easier to get at. I did not include them in this example.

UPDATE

I was able to rewrite the code and get at what I needed much more efficiently.

// NEW EXHIBITOR
BoothInfo.NewExhibitor = 0;
if (structKeyExists(ResponseNodes[i].CustomFields, "Field")) {
    Fields = ResponseNodes[i].CustomFields.Field;
    for (j = 1; j lte arrayLen(Fields); j++) {
        if (Fields[j].XmlAttributes.Name == "New Exhibitor") {
            BoothInfo.NewExhibitor = 1;
    break;
        }
}
}

解决方案

Well, I don't see why you're calling xmlParse over and over. You use that to convert a string to an XML nodeset, but you already have an XML nodeset.

You can use a more specific XPath specification for the nodes you want. Maybe something like, //*[ local-name() = 'OnlineBoothInformation' ]/CustomFields/Field[@Name="New Exhibitor"]. Then you can just check whether an empty array was returned. XPath is really expressive, but it takes some getting used to. Take care that while CF is generally not case-sensitive, XPath is. I copied the case from your CF, but that has to match the case in the XML in order to work.

这篇关于如何有效地测试和解析XML中的深层价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆