Home > Enterprise >  Access nested XML - JavaScript
Access nested XML - JavaScript

Time:11-10

How do I access the Id attribute of Detail and colorName of Color.

For example: using x[i].getAttribute('No') returns 0002. How do I access Id="6" and colorName="orange". Thank you.

<xml>
  <Items>
    <Item No="0001">
      <Details>
        <Detail Id="3">
          <Colors>
            <Color colorName="green" />
            <Color colorName="yellow" />
          </Colors>
        </Detail>
        <Detail Id="4">
          <Colors>
            <Color colorName="red" />
            <Color colorName="blue" />
          </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>
    <Item>
      <Details>
      </Details>
    </Item>
  </Items>
</xml>

The below code returns "0002":

var x = xmlDoc.getElementsByTagName("Item");
Number = '0002';

for (i = 0; i < x.length; i  ) {
  if (x[i].getAttribute('No') === Number) //desc
    ans = x[i].getAttribute('No') // returns 0002
}

Tried x[i].getElementsByTagName("Detail")[i].getAttribute('Id'), but dint work

CodePudding user response:

The best way to query some nodes and list them is probably to use XPath

see: https://developer.mozilla.org/en-US/docs/Web/XPath/Introduction_to_using_XPath_in_JavaScript

You can run a query inside any node (referenced as contextNode) using :

const xpathResult = xmlDocument.evaluate(xpathExpression, contextNode);

Which will give you a node iterator as a result, that you can then iterate using

let myVar;
while ( !! (myVar = xpathResult.iterateNext()) ) {
  //Do something with the result in myVar
}

Running example:

const SEARCH_NO = "0002";
const xmlDoc = loadXml(); //See function definition below
const rEl = document.querySelector("#results");

//Solution starts here

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

//Solution ends here

/**
 * Show a found details node as a li
 */
function showDetail(id) {
  const li = document.createElement('li');
  li.innerHTML = `<strong>Detail</strong> Id:  ${id}<ul></ul>`;
  rEl.append(li);
  return li;
}

/**
 * Show a found color attribute as a li within li
 */
function showColor(li, color) {
  const ul = li.querySelector('ul');
  const colLi = document.createElement('li');
  colLi.innerHTML = `<strong>Color:</strong>  ${color}`;
  ul.append(colLi);
  return colLi;
}

/**
 * Load the sample xml
 */
function loadXml() {
  const xml = `
  <xml>
    <Items>
      <Item No="0001">
        <Details>
          <Detail Id="3">
            <Colors>
              <Color colorName="green" />
              <Color colorName="yellow" />
            </Colors>
          </Detail>
          <Detail Id="4">
            <Colors>
              <Color colorName="red" />
              <Color colorName="blue" />
            </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>
      <Item>
        <Details>
        </Details>
      </Item>
    </Items>
  </xml>
  `;

  const parser = new DOMParser();
  return parser.parseFromString(xml, "application/xml");
}
body {
  font-family: sans-serif;
}
<ul id="results"></ul>

  • Related