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

如何判断DOM操作中当前处理的是哪个同名manufacturedMaterial节点?

问题描述

我有一个包含两个<manufacturedMaterial>元素的XML文件,使用代码NodeList nodes = dom.getElementsByTagName("manufacturedMaterial");获取节点后,添加子元素时发现子元素会被同时加到第二个<manufacturedMaterial>节点中。当前使用的循环代码如下:

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
}

请问有没有办法判断当前处理的是第一个还是第二个<manufacturedMaterial>节点?对应的XML结构如下:

<product>
    <manufacturedProduct classCode="MANU">
        <templateId root="1.3.6.1.4.1.12559.11.10.1.3.1.3.1"/>
        <templateId root="2.16.840.1.113883.10.20.1.53"/>
        <manufacturedMaterial classCode="MMAT" determinerCode="KIND">
            <code code="10219000" codeSystem="0.4.0.127.0.16.1.1.2.1" codeSystemName="EDQM" codeSystemVersion="2022-01-18" displayName="Tablet"/>
            <name>ALGOFEN TABLET 500MG</name>
            <epsos:desc xmlns="">500 mg</epsos:desc>
            <epsos:formCode xmlns="" code="658244" codeSystem="2.16.724.4.21.5.15.4" displayName="PARACETAMOL NORMON 500MG 20 COMPRIMIDOS EFG"/>
            <epsos:asContent xmlns="urn:epsos-org:ep:medication" classCode="CONT">
                <epsos:containerPackagedMedicine xmlns="" classCode="CONT" determinerCode="INSTANCE">
                    <epsos:name/>
                    <epsos:formCode code="116" codeSystem="1.3.6.1.4.1.12559.11.10.1.3.1.44.4" codeSystemName="eHDSIDisplayLabel" displayName=""/>
                    <epsos:capacityQuantity unit="1" value="20.0"/>
                    <epsos:capTypeCode nullFlavor="NA"/>
                </epsos:containerPackagedMedicine>
            </epsos:asContent>
            <epsos:asSpecializedKind xmlns="urn:epsos-org:ep:medication" classCode="GEN">
                <epsos:generalizedMedicineClass classCode="MMAT">
                    <code code="N02BE01" codeSystem="2.16.840.1.113883.6.73" codeSystemName="Anatomical Therapeutic Chemical" codeSystemVersion="2022-01" displayName="paracetamol"/>
                </epsos:generalizedMedicineClass>
            </epsos:asSpecializedKind>
        </manufacturedMaterial>
    </manufacturedProduct>
</product>
<entryRelationship typeCode="REFR">
    <sequenceNumber value="1"/>
    <substanceAdministration classCode="SBADM" moodCode="INT">
        <id extension="JE000233461" root="2.16.724.4.9.30.40"/>
        <text>
            <reference value="#medicine.1"/>
        </text>
        <statusCode code="completed"/>
        <effectiveTime nullFlavor="UNK" xsi:type="IVL_TS"/>
        <doseQuantity nullFlavor="UNK"/>
        <consumable typeCode="CSM">
            <manufacturedProduct classCode="MANU">
                <templateId root="1.3.6.1.4.1.12559.11.10.1.3.1.3.1"/>
                <templateId root="2.16.840.1.113883.10.20.1.53"/>
                <manufacturedMaterial classCode="MMAT" determinerCode="KIND">
                    <code code="10219000" codeSystem="0.4.0.127.0.16.1.1.2.1" codeSystemName="EDQM" codeSystemVersion="2022-01-18" displayName="Tablet"/>
                    <name>PARACETAMOL NORMON 500 mg COMPRIMIDOS EFGPARACETAMOL NORMON 500 mg COMPRIMIDOS EFG</name>
                    <epsos:formCode xmlns=""/>
                    <epsos:asContent xmlns="urn:epsos-org:ep:medication" classCode="CONT">
                        <epsos:containerPackagedMedicine xmlns="" classCode="CONT" determinerCode="INSTANCE">
                            <epsos:name/>
                            <epsos:formCode/>
                            <epsos:capacityQuantity/>
                            <epsos:capTypeCode nullFlavor="NA"/>
                        </epsos:containerPackagedMedicine>
                    </epsos:asContent>
                    <epsos:asSpecializedKind xmlns="urn:epsos-org:ep:medication" classCode="GEN">
                        <epsos:generalizedMedicineClass classCode="MMAT">
                            <code code="N02BE01" codeSystem="2.16.840.1.113883.6.73" codeSystemName="Anatomical Therapeutic Chemical" codeSystemVersion="2022-01" displayName="paracetamol"/>
                        </epsos:generalizedMedicineClass>
                    </epsos:asSpecializedKind>
                </manufacturedMaterial>
            </manufacturedProduct>
        </consumable>
    </substanceAdministration>
</entryRelationship>
解决方案

方法1:利用循环索引直接判断

循环变量i本身就是节点的序号(从0开始),直接通过i的值就能区分第一个和第二个节点:

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    if (i == 0) {
        // 处理第一个manufacturedMaterial节点
        // 示例:添加子元素
        Element newElem = dom.createElement("newElement");
        newElem.setTextContent("firstNodeContent");
        node.appendChild(newElem);
    } else if (i == 1) {
        // 处理第二个manufacturedMaterial节点
        Element newElem = dom.createElement("newElement");
        newElem.setTextContent("secondNodeContent");
        node.appendChild(newElem);
    }
}

方法2:通过节点上下文(父节点)区分

如果后续节点数量可能变化,可以通过节点的父级结构判断:

  • 第一个<manufacturedMaterial>的上层路径是<product>→<manufacturedProduct>
  • 第二个的上层路径是<entryRelationship>→<substanceAdministration>→<consumable>→<manufacturedProduct>

代码示例:

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    // 追溯到上层差异节点
    Node parent = node.getParentNode();
    Node grandParent = parent.getParentNode();
    if ("product".equals(grandParent.getNodeName())) {
        // 第一个节点
    } else if ("consumable".equals(grandParent.getNodeName())) {
        // 第二个节点
    }
}

方法3:通过节点内容差异区分

两个<manufacturedMaterial>的<name>子元素内容不同,也可以读取该值判断:

for (int i = 0; i < nodes.getLength(); i++) {
    Element material = (Element) nodes.item(i);
    Node nameNode = material.getElementsByTagName("name").item(0);
    String nameContent = nameNode.getTextContent();
    if (nameContent.contains("ALGOFEN")) {
        // 第一个节点
    } else if (nameContent.contains("PARACETAMOL NORMON")) {
        // 第二个节点
    }
}

关于子元素被重复添加的问题

你遇到的子元素同时出现在第二个节点的情况,大概率是因为重复使用了同一个Node对象。DOM规范中,一个节点只能属于一个父节点,当你把同一个子元素添加到新节点时,它会自动从原父节点移除。解决方法是:

  • 为每个目标节点重新创建子元素对象
  • 或者使用cloneNode(true)复制子元素后再添加,示例:
Element templateElem = dom.createElement("newElement");
templateElem.setTextContent("content");

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    // 复制子元素,true表示复制所有子节点
    Element clonedElem = (Element) templateElem.cloneNode(true);
    node.appendChild(clonedElem);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:10:48