【问题标题】:Consistently getting text from XML nodes一致地从 XML 节点获取文本
【发布时间】:2016-05-06 02:26:29
【问题描述】:

我知道这已经被问了很多,但我已经听从了建议,我仍然从我的 xml/jQuery 文件中得到一些非常具体、看似不一致的行为: 在我回答这个问题之前,这是我的 jQuery:

$(document).ready(function() {
    var $body = $('body');
    var currentXMLObjects;
    var $currentXMLContainers = new Array();
    var previousXMLObjects;
    $body.append("<div id='content'><h3>Staff Organisational Chart</h1></div>");
    // Load the xml file using ajax 
    $.ajax({
        type: "GET",
        url: "xml/content.xml",
        dataType: "xml",
        success: function (xml) {
            $xml = $(xml);
            console.log(xml.children[0]);
            appendNewContainers(xml.children[0].children);
        }
    });

    function appendNewContainers(children) {
        currentXMLObjects = children;
        console.log("currentXMLObjects.length = "+currentXMLObjects.length);
        for (var x=0;x<currentXMLObjects.length;x++) {
            $currentXMLContainers.push( $( currentXMLObjects[x] ) );
            $("#content").append('<div class="container"><div>' + currentXMLObjects[x].childNodes[1].firstChild.nodeValue + '</div><div>' + currentXMLObjects[x].childNodes[1].firstChild.nodeValue + '</div><div>' + currentXMLObjects[x].childNodes[1].firstChild.nodeValue + '</div></div>');
        }
    }
});

这是 XML:

<content>
    <level name="first name">
        <title>Title 1 Here</title>
        <firstName>First Name 1</firstName>
        <lastName>Last Name 1</lastName>
        <contact>Active</contact> 
    </level>
    <level name="second name">
        <title>Title 2 Here</title>
        <firstName>First Name 2</firstName>
        <lastName>Last Name 2</lastName>
        <contact>Active</contact>
    </level>
    <level name="third name">
        <title>Title 3 Here</title>
        <firstName>First Name 3</firstName>
        <lastName>Last Name 3</lastName>
        <contact>Active</contact>
    </level>
    <level name="fourth name">
        <title>Title 4 Here</title>
        <firstName>First Name 4</firstName>
        <lastName>Last Name 4</lastName>
        <contact>Active</contact>
    </level>
    <level name="fifth name">
        <title>Title 5 Here</title>
        <firstName>First Name 5</firstName>
        <lastName>Last Name 5</lastName>
        <contact>Active</contact>
    </level>
</content>

现在我要做的是从标题、名字和姓氏节点中获取文本,并将它们附加到 div 到包含的 div 中。

我花了一段时间,尝试了 .childNodes[0]、firstChild 和 nodeValue 的各种排列,才意识到我可以使用 currentXMLObjects[x] 中的索引“1”来获取每个“标题”的文本。 childNodes[1]... 问题是我似乎无法访问 firstName 和 lastName 节点。我已经尝试了所有我能想到的安排:

currentXMLObjects[x].childNodes[1].childNodes[1].nodeValue 抛出空错误,如下所示: currentXMLObjects[x].childNodes[0].childNodes[1].nodeValue

currentXMLObjects[x].childNodes[1].nodeValue 返回并附加'null',并且

currentXMLObjects[x].childNodes[2].nodeValue 不附加任何内容。

类似地,任何缺少中间 'childNodes[n]' 的组合都返回 null 或根本不返回任何内容。

有人知道这里发生了什么吗?我很惊讶“标题”节点似乎如此深入地嵌套在 XML 中。发送到“appendNewContainers”函数的节点列表已经被深入研究。但是在较浅的深度上寻找“级别”元素的子节点是行不通的。

任何帮助,非常感谢。 干杯。

【问题讨论】:

    标签: javascript jquery xml child-nodes


    【解决方案1】:

    你为什么不使用 jQuery 来处理 xml 数据呢?查看此示例(使用您当前的 xml 结构):jsFiddle

    var $target = $('content');
    $target.children().each(function(){
        $body.append($(this).attr('name') + "<br />");
        $body.append($('title', this).text() + "<br />");
        $body.append($('lastName', this).text() + "<br />");
        $body.append($('contact', this).text() + "<br />");
        $body.append('<br /><br/>');
    });
    

    编辑:

    使用您的代码结构(包括使用 jQuery 的示例):jsFiddle

    var xml = $('content');
    
    appendNewContainers(xml[0].children);
    
    function appendNewContainers(children) {
        currentXMLObjects = children;
    
        for (var x= 0; x < currentXMLObjects.length; x++) {
            $("#content").append(
                '<div class="container"><div>' + currentXMLObjects[x].children[0].innerText + 
                '</div><div>' + currentXMLObjects[x].children[1].innerText + 
                '</div><div>' + currentXMLObjects[x].children[2].innerText + '</div></div>'
            );
        }
    
        $('#content').append('<br style="margin-bottom: 40px" />');
    
        // jQuery way using tag names
        $(currentXMLObjects).each(function(){
            $("#content").append(
                '<div class="container"><div>' + $('title', this).text() + 
                '</div><div>' + $('firstName', this).text() + 
                '</div><div>' + $('lastName', this).text() + '</div></div>'
            );
        });
    }
    

    【讨论】:

    • 感谢您的回答-也许我应该说;我正在使用外部 xml 文件,以便管理员(或编码经验较少的人)能够更新 Web 应用程序。我真的很想知道我的简单设置发生了什么。
    • 加载后,外部文件会变成 xml 结构,就像我发布的示例一样。我认为你把事情复杂化了。您当前的代码不起作用,因为您正在尝试访问不存在的节点。我用你安排的代码更新了我的答案。
    • 再次感谢您的澄清。虽然我似乎无法使用外部 xml 文件来完成这项工作。我也不明白为什么我可以访问“标题”节点而不是其他节点。为什么这些节点不存在?
    • 制作一个console.log(或者最好使用断点)并自己检查对象的现有属性。我已经使用 xml 结构来填充 html 和地图,最简单的方法(使用 jQuery)是使用标签名称。查看并尝试使用此 jsfiddle 中的代码:jsfiddle.net/kmsdev/o1my8bm0。我认为这是最简单的方法。
    • 我一直在控制台记录这件事,但这并没有让它变得更清楚。当我返回一个文本对象时,我无法提取任何文本。有些对象会有长度,但我不能用方括号访问它们。此外,使用标签名称的问题是我只想获取特定深度的标签——因为用户在员工层次结构中上下遍历。我想我将切换到使用一种类型的标签('level')并使用属性(例如 name="name here")来描述每个元素。
    【解决方案2】:

    将检索到的 xml 附加到文档中并使用 querySelectors 查询内容是一个想法吗?类似的东西(简单的没有 jQuery 示例,但应该很容易使用 jQuery 来附加 xml 并查询它):

    var xml = document.querySelector('content');
    
    var names = document.querySelectorAll('[name]');
    var result = document.querySelector('#result');
    
    [].slice.call(names).forEach(
      function(nameElement) {
        result.textContent += 
          nameElement.querySelector('firstName').textContent + ' ' +
          nameElement.querySelector('lastName').textContent +
          '\n';
      } 
    );
    content {
      display: none;
     }
    <pre id="result"></pre>
    
    <content>
        <level name="first name">
            <title>Title 1 Here</title>
            <firstName>First Name 1</firstName>
            <lastName>Last Name 1</lastName>
            <contact>Active</contact> 
        </level>
        <level name="second name">
            <title>Title 2 Here</title>
            <firstName>First Name 2</firstName>
            <lastName>Last Name 2</lastName>
            <contact>Active</contact>
        </level>
        <level name="third name">
            <title>Title 3 Here</title>
            <firstName>First Name 3</firstName>
            <lastName>Last Name 3</lastName>
            <contact>Active</contact>
        </level>
        <level name="fourth name">
            <title>Title 4 Here</title>
            <firstName>First Name 4</firstName>
            <lastName>Last Name 4</lastName>
            <contact>Active</contact>
        </level>
        <level name="fifth name">
            <title>Title 5 Here</title>
            <firstName>First Name 5</firstName>
            <lastName>Last Name 5</lastName>
            <contact>Active</contact>
        </level>
    </content>

    【讨论】:

    • 我将把 'level' 元素嵌套在 'level' 元素中,所以我认为这种方法行不通;我试图将“级别”元素的“当前”深度传递给 appendNewContainers 函数(最终的网络应用程序将代表一个员工层次结构)。所以我不能通过 'name' 属性收集元素,因为所有深度的 'level' 元素都将具有该属性。
    • 如果您可以控制 XML,则应该可以向其添加唯一(数据)属性以识别特定(范围)元素。也许使用 json 也是一个可行的选择。
    • xml 需要尽可能简单,以便管理员可以维护 Web 应用程序(不会冒犯管理员)。知道为什么我可以访问“title”节点而不是“firstName”或“lastName”节点吗?
    猜你喜欢
    • 2020-06-12
    • 2013-04-01
    • 2011-11-04
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多