【问题标题】:XPATH doing a list of element without twinsXPATH 做一个没有双胞胎的元素列表
【发布时间】:2020-12-14 03:46:34
【问题描述】:

对于上下文,我可以为一个名为“模型”的属性为 ~1500 个名为“块”的对象设置约 300 个值,并且我尝试获取没有双胞胎的模型列表。

XML 文件如下所示:

<blocks>
    <block name="toto1">
        <property... />
        <property name="Shape" value="New" />
        <property ... />
        <property name="Model" value="xxx" />
        <property ... />
    </block>

    <block name="toto2">
        <property name="Shape" value="New" />
        <property ... />
        ...
        <property name="Model" value="yyy" />
        <property ... />
    </block>
    <block name="toto3">
        <property ... />
        <property name="Shape" value="New" />
        <property ... />
        <property name="Model" value="xxx" />
        <property ... />
        <property ... />
    </block>
    <block name="toto4">
        <property ... />
        <property name="Shape" value="Old" />
        <property name="Model" value="555" />
        <property ... />
    </block>
    <block name="toto5">
        <property ... />
        <property name="Shape" value="New" />
        <property name="Model" value="zzz" />
        <property ... />
    </block>
</blocks>

我通过在具有名称属性='形状'=新的节点父节点之前选择具有名称属性='模型'的值属性的值......嗯......看看我的路径^^ '他工作!但还不够

//block/property[@name="Shape"][@value="New"]/parent::block/property[@name="Model"]/@value

我需要这样做,否则我会得到意想不到的“模型”值.. 就像'形状=旧'。 {xxx,yyy,xxx,555,zzz}

所以我得到 {xxx,yyy,xxx,zzz} 但我想要 {xxx,yyy,zzz}

我得到一个包含 1500 个模型价值元素的列表,而我确实有大约 300 个独特的模型...

所以我使用带有临时数组的 JS 来避免双胞胎

if(!shapes[Modelvalue]){shapes[shapes.length]=Modelvalue; shapes[Modelvalue]=[shapes.length];}

但是我只能使用 Xpath 吗? 请求需要 4 秒,因为块数..

【问题讨论】:

  • block/property 是如何处理 HTML 的 - 请注意,stackoverflow 是一个严格的仅限英文网站
  • il n'y aucun 属性model。 il y a des attributs name pouvant avoir la valeur "model" déjà que ta question est confuse, si en plus tu using un vocabulaire ambigu, on va pas s'en sortir。 Donc tu veux récuprer toutes lesoccunces différentes des élements xml dont l'attribut est valueayant name="Model"。 que vient faire Shape" dans cette histoire ? -- et comme le fait remarquer Bravo stackoverflow est un site ou tout le monde doit s'exprimer en Anglais
  • 我已经翻译了 ^^ 但我希望什么是不稳定的:s thx for return !

标签: javascript xml xpath


【解决方案1】:

我更喜欢使用 DOMParser,因为我们可以使用 ES6 方法(querySelector ...),这样可以提供更清晰的代码。

那么就用一个Set()

let xmlData = `
<blocks>
    <block name="toto1">
        <property truc1="" />
        <property name="Shape" value="New" />
        <property truc2="" />
        <property name="Model" value="xxx" />
        <property truc3="" />
    </block>
    <block name="toto2">
        <property name="Shape" value="New" />
        <property truc1="" />
        <property name="Model" value="yyy" />
        <property truc2="" />
    </block>
    <block name="toto3">
        <property truc1="" />
        <property name="Shape" value="New" />
        <property truc2="" />
        <property name="Model" value="xxx" />
        <property truc3="" />
        <property truc4="" />
    </block>
    <block name="toto4">
        <property truc1="" />
        <property name="Shape" value="Old" />
        <property name="Model" value="555" />
        <property truc2="" />
    </block>
    <block name="toto5">
        <property truc1="" />
        <property name="Shape" value="New" />
        <property name="Model" value="zzz" />
        <property truc2="" />
    </block>
</blocks>`;

const parser  = new DOMParser()
  ,   docBLKs = parser.parseFromString(xmlData, "application/xml")
  ,   rSet    = new Set()
  ;
docBLKs.querySelectorAll('property[name="Shape"][value="New"]').forEach(sn=>
  {
  let model = sn.closest('block').querySelector('property[name="Model"]')
  rSet.add( model.getAttribute('value') )
  })

console.log( Array.from(rSet) ) 

【讨论】:

  • 谢谢!!我现在不明白你的代码中的所有内容:s 我开始......所以我会理解他是如何工作的 ^^ 什么是新的 set().add 和“让”太^^“我已经有了一个 DOMparse 函数,因为我的 XML 代码是从带有输入的文件中加载的。也许这会有所帮助。或者 querySelectorAll 和 querySelector 不是 JS ??(我刚刚发现它们:s)那么为什么 Xpath ?
  • 编辑:谢谢!!我明白了!!!这是因为 Set 不能有双胞胎.. 太棒了! querySelectorAll 是否像 xpath 一样更快?这不像我需要重写我的一半代码xD
【解决方案2】:

非常感谢乔乔先生! 这不是我所期望的,但效果很好! 我这样做:

function displayShapes()
  {
  ModelAttrPath  = '//block/property[@name="Shape"][@value="New"]/parent::block/property[@name="Model"]/@value';
  ModelAttrList  = xmlDoc.evaluate(ModelAttrPath, xmlDoc, null, XPathResult.ANY_TYPE, null);
  ModelAttrFocus = ModelAttrList.iterateNext();

  ModelList = new Set();
  while(ModelAttrFocus)
    {
    ModelList.add( ModelAttrFocus.value);
    ModelAttrFocus = ModelAttrList.iterateNext();
    }// $c(ModelList.size);

  //creat Tree dropdown
  cnt = '<div id="tree">';
  for(elements of ModelList)
    {
    cnt += '<button class="treeB">'+elements+'</button><div class="treeP"></div>';
    }
  cnt += '</div>';
  $('divMenu2').innerHTML = cnt;
  treeD(); //init du addEventListener click pour la creation du menu 
  $('tree').style.height = $('divMenu2').style.height;
  }

我在不到 1 秒的时间内获得了我的模型树菜单 :) 完美! 下一步寻找 querySelector !

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多