Home > OS >  Accessing nested XML - going upwards
Accessing nested XML - going upwards

Time:11-11

How do I find Item No = "0002" , if Detail ID = "5" is given?

const Detail_id= "5";

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

How do I go upward now to find Item No = "0002"

<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>

Below code works fine. For going downwards. Below gives all details of <Item No="0002">. Like Detail Ids and colorNames

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);
    }
  }
}

CodePudding user response:

Instead of "going upward" after selecting your targeted Detail, adapt your XPath to select the targeted Item directly by adding a predicate to it.

Change

//Item/Details/Detail[@Id="${Detail_id}"]

to

//Item[@No="${SEARCH_NO}" and Details/Detail/@Id="${Detail_id}"]

Or, if you don't know SEARCH_NO and just wish to find the Item ancestor of the targeted Detail,

//Item[Details/Detail/@Id="${Detail_id}"]

From comments:

Yes, I need to find the search_no.

Then

//Item[Details/Detail/@Id="${Detail_id}"]/@No

See also

  • Related