【问题标题】:XML: Select nodes by it's value instead of attributeXML:通过它的值而不是属性选择节点
【发布时间】:2015-05-14 09:09:04
【问题描述】:

我有这段代码可以根据孩子的属性从 xml 列表中删除不需要的项目。

var xmlDoc=loadXMLDoc(filePath);

var unwanted = xmlDoc.querySelectorAll("item > KlasId[id='1']");
Array.prototype.map.call(unwanted, function(element){
    element.parentNode.parentNode.removeChild(element.parentNode);
});

这工作得很好,并删除了所有item 具有KlasId 子节点的id=1 节点。

我现在想要的是基于 KlasId value 而不是 attribute (例如值 101010)删除 items,但它在某种程度上不起作用:

var unwanted = xmlDoc.querySelectorAll("item > KlasId[value='101010']");
etc...

我的 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<dataroot>
<item>
<KlasId id='1'>101010</KlasId>
</item>

<item>
<KlasId id='2'>101010</KlasId>
</item>

<item>
<KlasId id='3'>202020</KlasId>
</item>
</dataroot>

编辑:

function loadXMLDoc(filename)
{
if (window.XMLHttpRequest)
  {
  xhttp=new XMLHttpRequest();
  }
else // code for IE5 and IE6
  {
  xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xhttp.open("GET",filename,false);
xhttp.send();
return xhttp.responseXML;
}

【问题讨论】:

  • loadXMLDoc 是什么? code.google.com/p/dingweiwang/downloads/… 也许?
  • loadXMLDoc 加载 xml。它工作得很好。
  • 您是在浏览器中执行此操作,还是在 Node 之类的工具中执行此操作?
  • 是的,这不是我问的。没关系,你接下来使用querySelectorAll 所以我猜loadXMLDoc 返回一个DOM 文档。 querySelectorAll 接受 CSS 选择器。没有用于按节点值选择的 CSS 选择器。你试图做的事情是不可能的。阅读:stackoverflow.com/questions/4811962/…(您需要自定义 JS。jQuery 有一个 contains 选择器,例如专门为此)。
  • @JLRishe 浏览器 (Chrome),SergiuParaschiv,抱歉,请检查我的编辑。

标签: javascript xml xpath css-selectors


【解决方案1】:

你不能只用 CSS 来做,因为没有 CSS 选择器可以通过元素的值来选择。请参阅此博文:Blog

【讨论】:

    【解决方案2】:

    如果您只使用 Chrome(或 Firefox、Opera 或 Safari),那么您可以使用 XPath 来执行此选择:

    var found = xmlDoc.evaluate("/*/item[KlasId = '101010']", xmlDoc);
    

    这将返回一个节点迭代器,您可以使用它来遍历节点,如here 所述。

    function getNodes(iterator) {
        var nodes = [],
            next = iterator.iterateNext();
    
        while (next) {
            nodes.push(next);
            next = iterator.iterateNext();
        }
        return nodes;
    }
    
    getNodes(found).forEach(function (node) {
        node.parentNode.removeChild(node);
    });
    

    var xmlDoc = $.parseXML("<dataroot><item><KlasId id='1'>101010</KlasId></item><item><KlasId id='2'>101010</KlasId></item><item><KlasId id='3'>202020</KlasId></item></dataroot>");
    
    var found = xmlDoc.evaluate("//item[KlasId = '101010']", xmlDoc);
    
    function getNodes(iterator) {
        var nodes = [],
            next = iterator.iterateNext();
    
        while (next) {
            nodes.push(next);
            next = iterator.iterateNext();
        }
        return nodes;
    }
    
    getNodes(found).forEach(function (node) {
        console.log('Removing node.');
        node.parentNode.removeChild(node);
    });
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"&gt;&lt;/script&gt;

    Internet Explorer 不支持.evaluate()(或据我所知的任何 XPath 功能),因此如果您需要跨浏览器支持,我认为您需要使用第三方库。我推荐xpath.js,我是其中的贡献者。

    另一种选择是使用 jQuery 的扩展 CSS 选择器来执行选择:

    var $nodes = $(xmlDoc).find('item > KlasId:contains("101010")');
    
    $nodes.remove();
    

    var xmlDoc = $.parseXML("<dataroot><item><KlasId id='1'>101010</KlasId></item><item><KlasId id='2'>101010</KlasId></item><item><KlasId id='3'>202020</KlasId></item></dataroot>");
    
    var $nodes = $(xmlDoc).find('item > KlasId:contains("101010")');
    
    console.log($nodes.length);
    
    $nodes.remove();
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"&gt;&lt;/script&gt;

    这也是一个跨浏览器的解决方案,但它会根据 contains 比较而不是相等比较来选择元素。

    不相关的旁注:.map() 用于将一个阵列投影到另一个阵列上。要执行一系列副作用,请使用.forEach()

    【讨论】:

    • 我不需要跨浏览器,它供个人使用,根据我的需要更改现有的大型 xml 文件。
    • JLRishe,还有一个问题。逆向选择如何?在我的旧代码中,我使用了 :not 运算符。这应该在 xpath 表达式本身内部处理还是有其他解决方案?
    • @devbull XPath 应该能够处理它。你能举个例子吗?
    • 例如:不包括 KlasId 值为 101010 和 303030 的所有项目节点。
    • @devbull /*/item[KlasId != '101010' and KlasId != '303030']
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多