处理服务器 XML 响应

Processing Server XML Response

所以我正在为考试而学习,我只有一个困扰我一段时间的快速问题。我使用 AJAX 获取 XML 文件来解析它并将其值插入到 select 元素中。这是代码:

<html>  
    <head>  
    </head>
    <body>  
        <button onclick="EnviaPedido()">Submeter</button>       
        <select id="select"></select>   

        <script type="text/javascript">             
                var xmlHttpObj;
                function CreateXmlHttpRequestObject() { 
                    if (window.XMLHttpRequest) {
                        xmlHttpObj = new XMLHttpRequest() 
                    }
                    else if (window.ActiveXObject) {
                        xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP")
                    }
                    return xmlHttpObj;          
                }

                function EnviaPedido() {
                    xmlHttpObj = CreateXmlHttpRequestObject();
                    xmlHttpObj.open("POST", "agenda.xml", true);
                    xmlHttpObj.onreadystatechange = ProcessaReposta;
                    xmlHttpObj.send();          
                }

                function ProcessaReposta() {
                    if (xmlHttpObj.readyState == 4 && xmlHttpObj.status == 200) {
                        var response = xmlHttpObj.responseText;

                        var xmlDoc;

                        if (window.DOMParser) {
                            parser = new DOMParser();
                            xmlDoc = parser.parseFromString(response, "text/xml");
                        } else {
                            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                            xmlDoc.async = false;
                            xmlDoc.loadXML(response);
                        }

                        var select = document.getElementById("select");

                        var centrosInvestigacao = xmlDoc.getElementsByTagName("centro_de_investigacao");

                        for(i = 0; i < centrosInvestigacao.length; i++) {
                            var option = document.createElement("option");
                            option.innerHTML = centrosInvestigacao[i].childNodes[1].textContent;
                            select.appendChild(option);
                        }
                    }   
                }       
            </script>   
        <body>      
    </html>

这是返回的 XML:

    <FCT>
      <centro_de_investigacao id="1">
        <nome>GECAD</nome>
        <local>ISEP</local>
        <classificao>Muito bom</classificao>
      </centro_de_investigacao>
      <centro_de_investigacao id="2">
        <nome>DEF</nome>
        <local>ISEP</local>
        <classificao>Bom</classificao>
      </centro_de_investigacao>
      <centro_de_investigacao id="3">
        <nome>ABC</nome>
        <local>FEUP</local>
        <classificao>Muito mau</classificao>
      </centro_de_investigacao>
    </FCT>

所以当我想获取'nome'字段时为什么我必须使用

option.innerHTML = centrosInvestigacao[i].childNodes[1].textContent;

而不是

option.innerHTML = centrosInvestigacao[i].childNodes[0].textContent;

我知道这可能是一个愚蠢的问题,但它开始让我生气,因为我不知道这是预期的行为还是我搞砸了。

谢谢。

我做了一个问题的小片段,其中也显示了部分答案。我认为您正在解析的 XML 文档的编码是 "off",因为您的 childNodes 的第一个元素实际上是 centro_de_investigacao> 的最后一个引号之间的文本节点和 的开始标签

如果您检查片段集(例如,您可以尝试使用 index 参数),您会发现第一个按钮不需要将索引增加到 1,但可以按预期使用第一个元素, nl 索引为 0.

所以从你的 XML 文档中删除白色spaces,你应该没问题。

白色spaces: 制表符,space,换行符

// mocked, no real data
var xmlHttpObj;

function CreateXmlHttpRequestObject() {
  
  function Mock() {
    this.callready = function() {
      this.readyState = 4;
      this.status = 200;
      this.statusMsg = "OK";
      if (this.onreadystatechange && this.onreadystatechange.call) {
        setTimeout(this.onreadystatechange.bind(this), 0);
      }
    };
    
    this.open = function(methodType, url, async) {
      var el = document.getElementById('dataXml-' + url.split('.')[0]),
          content = el ? el.innerHTML : '';
      if (typeof async === 'undefined' || async) {
        // no action till send is executed
        this.responseText = content;
        this.responseXml = content;
        return;
      }
      return content;
    };
      
    this.send = function(data) {
        this.callready();
    };
  }
  return new Mock();
}

function EnviaPedido(index, url) {
  xmlHttpObj = CreateXmlHttpRequestObject();
  xmlHttpObj.open("POST", url, true);
  xmlHttpObj.onreadystatechange = ProcessaReposta.bind(this, index);
  xmlHttpObj.send();
}

function ProcessaReposta(index, url) {
  if (xmlHttpObj.readyState == 4 && xmlHttpObj.status == 200) {
    var response = xmlHttpObj.responseText;

    var xmlDoc;

    if (window.DOMParser) {
      parser = new DOMParser();
      xmlDoc = parser.parseFromString(response, "text/xml");
    } else {
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.async = false;
      xmlDoc.loadXML(response);
    }

    var select = document.getElementById("select");

    var centrosInvestigacao = xmlDoc.getElementsByTagName("centro_de_investigacao");
    select.options = [];

    for (i = 0; i < centrosInvestigacao.length; i++) {
      var option = new Option();
      var item = centrosInvestigacao[i].childNodes[index];
      option.text = item.textContent;
      select.options[i] = option;
    }
  }
}
<template id="dataXml-agenda"><FCT><centro_de_investigacao id="1"><nome>GECAD</nome><local>ISEP</local><classificao>Muito bom</classificao></centro_de_investigacao><centro_de_investigacao id="2"><nome>DEF</nome><local>ISEP</local><classificao>Bom</classificao></centro_de_investigacao><centro_de_investigacao id="3"><nome>ABC</nome><local>FEUP</local><classificao>Muito mau</classificao></centro_de_investigacao></FCT></template>
<template id="dataXml-original-agenda"><FCT>
<centro_de_investigacao id="1">
  <nome>GECAD</nome>
  <local>ISEP</local>
  <classificao>Muito bom</classificao>
</centro_de_investigacao>
<centro_de_investigacao id="2">
  <nome>DEF</nome>
  <local>ISEP</local>
  <classificao>Bom</classificao>
</centro_de_investigacao>
<centro_de_investigacao id="3">
  <nome>ABC</nome>
  <local>FEUP</local>
  <classificao>Muito mau</classificao>
</centro_de_investigacao>
</FCT></template>
<select id="select"></select>
<button id="btnGenerate" type="button" onclick="EnviaPedido(0, 'agenda.xml');">Get info</button>
<button id="btnGenerate" type="button" onclick="EnviaPedido(1, 'original-agenda.xml');">Get info false contentType</button>