提取和解析 XML 以表格式显示在不同的节点级别

Extract and Parse XML to show in table format on different node level

提问人:Ragul 提问时间:9/14/2023 最后编辑:Ragul 更新时间:9/16/2023 访问量:75

问:

我有以下从API返回的XML格式。

我需要以表格格式提取并重新解析回相同的格式。

XML 1:

<steps id="0" last="4">
    <step id="2" type="ValidateStep">
        <parameterizedString isformatted="true">Stp 001</parameterizedString>
        <parameterizedString isformatted="true">Act 001</parameterizedString>
    </step>
    <compref id="4" ref="89">
        <step id="3" type="ValidateStep">
            <parameterizedString isformatted="true">Stp 003</parameterizedString>
            <parameterizedString isformatted="true">Act 003</parameterizedString>
        </step>
    </compref>
</steps>

预期输出:

Array = [{step: 1, action:Stp 001, result:Act 001 },
         {step: 2, compref,        result:ref-89 },
         {step: 3, action:Stp 003, result:Act 003 }]

XML 2:

<steps id="0" last="6">
    <step id="2" type="ValidateStep">
        <parameterizedString isformatted="true">Stp 001</parameterizedString>
        <parameterizedString isformatted="true">Act 001</parameterizedString>
    </step>
    <compref id="4" ref="89">
        <step id="3" type="ValidateStep">
            <parameterizedString isformatted="true">Stp 003</parameterizedString>
            <parameterizedString isformatted="true">Act 003</parameterizedString>
        </step>
        <compref id="5" ref="91">
            <step id="6" type="ActionStep">
                <parameterizedString isformatted="true">Stp 005</parameterizedString>
                <parameterizedString isformatted="true">Act 005</parameterizedString>
            </step>
        </compref>
    </compref>
</steps>

预期输出:

Array = [{step: 1, action:Stp 001, result:Act 001 },
         {step: 2, compref,        result:ref-89 },
         {step: 3, action:Stp 003, result:Act 003 },
         {step: 4, compref,        result:ref-91 },
         {step: 5, action:Stp 005, result:Act 005 }]

XML 3:

<steps id="0" last="9">
    <compref id="6" ref="90">
        <compref id="4" ref="89">
            <step id="7" type="ActionStep">
                <parameterizedString isformatted="true">Stp 003</parameterizedString>
                <parameterizedString isformatted="true">Act 003</parameterizedString>
            </step>
            <compref id="8" ref="91">
                <step id="9" type="ActionStep">
                    <parameterizedString isformatted="true">Stp 005</parameterizedString>
                    <parameterizedString isformatted="true">Act 005</parameterizedString>
                </step>
            </compref>
        </compref>
    </compref>
</steps>

预期输出:

Array = [{step: 1, compref,        result:ref-90 },
         {step: 2, compref,        result:ref-89 },
         {step: 3, action:Stp 003, result:Act 003 },
         {step: 4, compref,        result:ref-91 },
         {step: 5, action:Stp 005, result:Act 005 }]

我的代码

const strXML = '**above XML string'
        const steps = [...strXML.querySelectorAll('step')];
        const stepData = new Array;
        steps.forEach((value, index) => {
            stepData.push({
                step: index + 1,
                action: value.querySelectorAll("parameterizedString")[0].textContent,
                result: value.querySelectorAll("parameterizedString")[1].textContent
            });
        });

上面的代码只是提取步骤标签,我们该如何提取?compref

上面的数组也需要转换回XML格式。

JavaScript 数组 JSON XML

评论

0赞 LMC 9/14/2023
输出 xpath 是 ,对吗?//compref[@id="4"]/compref[@id="5"]
0赞 Ragul 9/14/2023
不同的是,我们不能在 ID 上中继,因为在源系统步骤中可以移动到任何行。
0赞 LMC 9/14/2023
问题是是否可以如图所示嵌套。compref
0赞 Ragul 9/14/2023
是的,它是正确的。@LMC
0赞 Ragul 9/14/2023
我直接用了,但我知道这不是正确的方式let fullSteps=''; this.data.forEach((value) => { fullSteps+='<step id="'+(value.step+1)+'" type="ValidateStep">'+ '<parameterizedString isformatted="true">'+encodeHTMLEntities(value.action)+'</parameterizedString>'+ '<parameterizedString isformatted="true">'+encodeHTMLEntities(value.result)+'</parameterizedString>'+ '</step>'; });

答:

1赞 Max Voisard 9/14/2023 #1

也许这就是你要找的?我不确定这是否是您在最终 XML 字符串中期望的确切格式,但它应该很接近。

您可以简单地按顺序遍历 XML 标记,并根据每个元素是否为 or 标记来提取每个元素的内容。comprefstep

const strXML = '<steps id="0" last="9"><compref id="6" ref="90"><compref id="4" ref="89"><step id="7" type="ActionStep"><parameterizedString isformatted="true">Stp 003</parameterizedString><parameterizedString isformatted="true">Act 003</parameterizedString></step><compref id="8" ref="91"><step id="9" type="ActionStep"><parameterizedString isformatted="true">Stp 005</parameterizedString><parameterizedString isformatted="true">Act 005</parameterizedString></step></compref></compref></compref></steps>';
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(strXML, "text/xml");
const nodes = [...xmlDoc.querySelectorAll("steps *")];
var stepData = new Array();
nodes.filter(function(value) {
   if (value.tagName == "compref") {
      stepData.push({
         step: stepData.length + 1,
         action: "compref",
         result: value.getAttribute("ref")
      });
   }
   else if (value.tagName == "step") {
      stepData.push({
         step: stepData.length + 1,
         action: value.querySelectorAll("parameterizedString")[0].textContent,
         result: value.querySelectorAll("parameterizedString")[1].textContent
      });
   }
});
console.log(stepData);
var xmlString = "<steps id='0' last='" + stepData.length + "'>";
stepData.filter(function(value) {
   xmlString += `<step id="${value.step}" type="ValidateStep"><parameterizedString isformatted="true">${value.action}</parameterizedString><parameterizedString isformatted="true">${value.result}</paramaterizedString></step>`;
});
xmlString += "</steps>";
var indentedXMLString = xmlString.replaceAll("<step ", "\n\t<step ").replaceAll("<parameterizedString", "\n\t\t<parameterizedString").replaceAll("</step>", "\n\t</step>").replace("</steps>", "\n</steps>");
console.log(indentedXMLString);

评论

0赞 Ragul 9/15/2023
让我试着回到你的代码上,谢谢你的努力:)
0赞 Ragul 9/15/2023
它不适用于内部,更新了 XML 3 示例。@Max Voisardcompref
0赞 Max Voisard 9/16/2023
@Ragul 请参阅我编辑的答案,您可以在其中遍历标签。
1赞 Ragul 9/16/2023
它奏效了,完美的!!!!!