使用递归解析高度嵌套的 XML 以获取所有 sys_id 直到 'TestBS4' 为每个 child of `<childrenOfCurrentCI>`
Parse a highly nested XML to fetch all the sys_id's till 'TestBS4' for each child of `<childrenOfCurrentCI>` using recursion
工具:ServiceNow。语言:JavaScript
我的方法:我在每个级别使用 while 循环进行迭代以达到'TestBS4'的sys_id,我必须在其中放置 4 个 while 循环另一个一旦我在 <childrenOfCurrentCI>
标签内有了第一个 <CI>...</CI>
节点。我觉得这可以通过递归来完成,但我做不到。
如果我有 50 个 CI child 一个在另一个里面(不是兄弟姐妹),我需要第 45 个怎么办?我很感激有人使用递归来帮助实现这一目标。
sys_id 可以放在数组中以供进一步处理。
在这种情况下,我需要 <childrenOfCurrentCI>
的每个 child 的所有 sys_id 直到第 4 级(TestBS4) 标签。
下面是示例 XML。
<?xml version="1.0" encoding="UTF-8"?>
<xmlTree>
<sys_id>e9c23f4adbf31300ae2af28239961974</sys_id>
<name>Test CI One</name>
<relType>SELF</relType>
<childrenOfCurrentCI>
<CI>
<sys_id>68b1b746dbf31300ae2af2823996197a</sys_id>
<name>TestBS1</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>964477cedbf31300ae2af28239961913</sys_id>
<name>TestBS2</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>88643fcedbf31300ae2af2823996190b</sys_id>
<name>TestBS3</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>0264f7cedbf31300ae2af28239961971</sys_id>
<name>TestBS4</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>fb64ffcedbf31300ae2af282399619e8</sys_id>
<name>TestBS5</name>
<relType>Depends on::Used by</relType>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
<CI>
<sys_id>ae1ff02fdbfb1300ae2af2823996195d</sys_id>
<name>Test Side Parent One</name>
<relType>Depends on::Used by</relType>
</CI>
</childrenOfCurrentCI>
</xmlTree>
刚刚为案例编码
In this case, I need all the sys_id's till the 4th level (TestBS4) of
each child of tag.
希望你明白了。
var text = `
<xmlTree>
<sys_id>e9c23f4adbf31300ae2af28239961974</sys_id>
<name>Test CI One</name>
<relType>SELF</relType>
<childrenOfCurrentCI>
<CI>
<sys_id>68b1b746dbf31300ae2af2823996197a</sys_id>
<name>TestBS1</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>964477cedbf31300ae2af28239961913</sys_id>
<name>TestBS2</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>88643fcedbf31300ae2af2823996190b</sys_id>
<name>TestBS3</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>0264f7cedbf31300ae2af28239961971</sys_id>
<name>TestBS4</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>fb64ffcedbf31300ae2af282399619e8</sys_id>
<name>TestBS5</name>
<relType>Depends on::Used by</relType>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
<CI>
<sys_id>ae1ff02fdbfb1300ae2af2823996195d</sys_id>
<name>Test Side Parent One</name>
<relType>Depends on::Used by</relType>
</CI>
</childrenOfCurrentCI>
</xmlTree>
`;
if (window.DOMParser)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(text);
}
let sysIds = xmlDoc.getElementsByTagName("childrenOfCurrentCI")[0].getElementsByTagName("sys_id");
function getMeSysId(position) {
console.log(sysIds[position-1].textContent);
}
console.log("to get the 4th level sys_Id");
getMeSysId(4);
console.log("for all the sysid's inside childrenOfCurrentCI");
for (let i=0; i<sysIds.length;i++) {
console.log(sysIds[i].textContent);
}
使用 var
而不是 let
else 条件可以跳过(IE 版本需要)
并尝试使用 serviceNow xml dom parser
所以更新后的代码块是
xmlDoc = new XMLDocument(text);
var sysIds = xmlDoc.getElementsByTagName("childrenOfCurrentCI")[0].getElementsByTagName("sys_id");
如果您希望通过 XML 的名称检索 CI 的 sys_id,我建议使用 XPath,它是 XML 操作的辅助工具。 ServiceNow XMLDocument2
对象将帮助您解析您的 XML。这是您案例的示例代码
var xmlString = 'YOUR_XML';
var ciName = 'TestBS4';
var xPath = "//CI/name[text() = '" + ciName + "']/../sys_id/text()";
var xmlDoc = new XMLDocument2();
xmlDoc.parseXML(xmlString);
var sysID = xmlDoc.getNode(xPath).toString();
gs.log(sysID);
getNode
方法中使用的 XPath 在 XML 中查找具有 ciName
变量值的 CI/name
节点。然后向上一个节点检索 sys_id
节点的值。
工具:ServiceNow。语言:JavaScript
我的方法:我在每个级别使用 while 循环进行迭代以达到'TestBS4'的sys_id,我必须在其中放置 4 个 while 循环另一个一旦我在 <childrenOfCurrentCI>
标签内有了第一个 <CI>...</CI>
节点。我觉得这可以通过递归来完成,但我做不到。
如果我有 50 个 CI child 一个在另一个里面(不是兄弟姐妹),我需要第 45 个怎么办?我很感激有人使用递归来帮助实现这一目标。 sys_id 可以放在数组中以供进一步处理。
在这种情况下,我需要 <childrenOfCurrentCI>
的每个 child 的所有 sys_id 直到第 4 级(TestBS4) 标签。
下面是示例 XML。
<?xml version="1.0" encoding="UTF-8"?>
<xmlTree>
<sys_id>e9c23f4adbf31300ae2af28239961974</sys_id>
<name>Test CI One</name>
<relType>SELF</relType>
<childrenOfCurrentCI>
<CI>
<sys_id>68b1b746dbf31300ae2af2823996197a</sys_id>
<name>TestBS1</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>964477cedbf31300ae2af28239961913</sys_id>
<name>TestBS2</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>88643fcedbf31300ae2af2823996190b</sys_id>
<name>TestBS3</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>0264f7cedbf31300ae2af28239961971</sys_id>
<name>TestBS4</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>fb64ffcedbf31300ae2af282399619e8</sys_id>
<name>TestBS5</name>
<relType>Depends on::Used by</relType>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
<CI>
<sys_id>ae1ff02fdbfb1300ae2af2823996195d</sys_id>
<name>Test Side Parent One</name>
<relType>Depends on::Used by</relType>
</CI>
</childrenOfCurrentCI>
</xmlTree>
刚刚为案例编码
In this case, I need all the sys_id's till the 4th level (TestBS4) of each child of tag.
希望你明白了。
var text = `
<xmlTree>
<sys_id>e9c23f4adbf31300ae2af28239961974</sys_id>
<name>Test CI One</name>
<relType>SELF</relType>
<childrenOfCurrentCI>
<CI>
<sys_id>68b1b746dbf31300ae2af2823996197a</sys_id>
<name>TestBS1</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>964477cedbf31300ae2af28239961913</sys_id>
<name>TestBS2</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>88643fcedbf31300ae2af2823996190b</sys_id>
<name>TestBS3</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>0264f7cedbf31300ae2af28239961971</sys_id>
<name>TestBS4</name>
<relType>Depends on::Used by</relType>
<children>
<CI>
<sys_id>fb64ffcedbf31300ae2af282399619e8</sys_id>
<name>TestBS5</name>
<relType>Depends on::Used by</relType>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
</children>
</CI>
<CI>
<sys_id>ae1ff02fdbfb1300ae2af2823996195d</sys_id>
<name>Test Side Parent One</name>
<relType>Depends on::Used by</relType>
</CI>
</childrenOfCurrentCI>
</xmlTree>
`;
if (window.DOMParser)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
}
else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(text);
}
let sysIds = xmlDoc.getElementsByTagName("childrenOfCurrentCI")[0].getElementsByTagName("sys_id");
function getMeSysId(position) {
console.log(sysIds[position-1].textContent);
}
console.log("to get the 4th level sys_Id");
getMeSysId(4);
console.log("for all the sysid's inside childrenOfCurrentCI");
for (let i=0; i<sysIds.length;i++) {
console.log(sysIds[i].textContent);
}
使用 var
而不是 let
else 条件可以跳过(IE 版本需要)
并尝试使用 serviceNow xml dom parser
所以更新后的代码块是
xmlDoc = new XMLDocument(text);
var sysIds = xmlDoc.getElementsByTagName("childrenOfCurrentCI")[0].getElementsByTagName("sys_id");
如果您希望通过 XML 的名称检索 CI 的 sys_id,我建议使用 XPath,它是 XML 操作的辅助工具。 ServiceNow XMLDocument2
对象将帮助您解析您的 XML。这是您案例的示例代码
var xmlString = 'YOUR_XML';
var ciName = 'TestBS4';
var xPath = "//CI/name[text() = '" + ciName + "']/../sys_id/text()";
var xmlDoc = new XMLDocument2();
xmlDoc.parseXML(xmlString);
var sysID = xmlDoc.getNode(xPath).toString();
gs.log(sysID);
getNode
方法中使用的 XPath 在 XML 中查找具有 ciName
变量值的 CI/name
节点。然后向上一个节点检索 sys_id
节点的值。