You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套XML向上节点查询:已知Detail ID获取对应Item No方法

从指定Detail节点向上查找所属Item节点

问题背景

已通过以下代码定位到**Id属性值为“5”**的<Detail>节点:

const Detail_id= "5";

let xRes = xmlDoc.evaluate(`//Item/Details/Detail[@Id="${Detail_id}"]`, 
xmlDoc.documentElement);

需要从该节点向上遍历嵌套XML结构,找到其所属的<Item No="0002">节点。

对应XML结构

<xml>
  <Items>
    <Item No="0001">
      <Details>
        <Detail Id="3">
          <Colors>
            <Color colorName="green" />
            <Color colorName="yellow" />
          </Colors>
        </Detail>
      </Details>
    </Item>
    <Item No="0002">
      <Details>
        <Detail Id="5">
          <Colors>
            <Color colorName="purple" />
            <Color colorName="pink" />
          </Colors>
        </Detail>
        <Detail Id="6">
          <Colors>
            <Color colorName="grey" />
            <Color colorName="orange" />
          </Colors>
        </Detail>
      </Details>
    </Item>
  </Items>
</xml>

参考:向下查询指定Item的详情代码

以下代码可正常运行,用于获取<Item No="0002">的所有详情(包括Detail的Id及colorName属性值):

const SEARCH_NO = "0002";

let xRes = xmlDoc.evaluate(`//Item[@No="${SEARCH_NO}"]`, xmlDoc.documentElement);
const foundNode = xRes.iterateNext();
if (foundNode) {
  xRes = xmlDoc.evaluate('Details/Detail', foundNode);
  let detailNode;
  while ( !!( detailNode = xRes.iterateNext() ) ) {
    const li = showDetail(detailNode.getAttribute("Id"));
    const colXres = xmlDoc.evaluate('Colors/Color/@colorName', detailNode);
    let colorTextNode;
    while ( !!( colorTextNode = colXres.iterateNext() ) ) {
      showColor(li, colorTextNode.textContent);
    }
  }
}

解决方案

方法1:使用XPath的ancestor轴直接查询

利用XPath的祖先轴ancestor::Item[1],可以直接从已定位的Detail节点获取最近的父Item节点,代码如下:

const Detail_id= "5";
// 先定位到目标Detail节点
let xRes = xmlDoc.evaluate(`//Item/Details/Detail[@Id="${Detail_id}"]`, xmlDoc.documentElement);
const detailNode = xRes.iterateNext();

if (detailNode) {
  // 查询最近的Item父节点
  const itemXRes = xmlDoc.evaluate('ancestor::Item[1]', detailNode);
  const itemNode = itemXRes.iterateNext();
  
  if (itemNode) {
    // 验证结果,输出Item的No属性
    console.log(itemNode.getAttribute("No")); // 输出:0002
  }
}

说明:ancestor::Item[1]表示匹配当前节点的所有祖先节点中的第一个Item节点,也就是距离当前Detail节点最近的父Item节点,无需手动逐层遍历。

方法2:通过DOM节点的parentNode逐层向上遍历

如果需要手动控制遍历逻辑,可以通过节点的parentNode属性逐层向上检查节点名称,直到找到Item节点:

const Detail_id= "5";
// 先定位到目标Detail节点
let xRes = xmlDoc.evaluate(`//Item/Details/Detail[@Id="${Detail_id}"]`, xmlDoc.documentElement);
const detailNode = xRes.iterateNext();

if (detailNode) {
  let currentNode = detailNode;
  // 逐层向上遍历,直到找到Item节点
  while (currentNode && currentNode.nodeName !== "Item") {
    currentNode = currentNode.parentNode;
  }
  
  if (currentNode) {
    // 验证结果,输出Item的No属性
    console.log(currentNode.getAttribute("No")); // 输出:0002
  }
}

说明:这种方法适合需要在遍历过程中添加额外判断逻辑的场景,比如中途需要检查其他节点类型。

内容的提问来源于stack exchange,提问作者Sarahrb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 04:05:40