Java修改XML属性后出现xmlns=""问题咨询
XML修改后出现
xmlns=""的问题解决 问题
修改XML文件属性值时,删除原有属性再添加同名新属性后,生成的XML中大量元素出现xmlns=""声明,破坏了原有的命名空间结构。
初始XML
<ClinicalDocument xmlns="urn:hl7-org:v3" classCode="DOCCLIN" moodCode="EVN" xmlns:pharm="urn:hl7-org:pharm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <realmCode code="CY"/> <typeId extension="POCD_HD000040" root="2.16.840.1.113883.1.3"/> <templateId root="1.3.6.1.4.1.12559.11.10.1.3.1.1.2"/> <templateId root="1.3.6.1.4.1.19376.1.5.3.1.1.1"/> <id extension="1.2.3.4.5.6" root="2.16.840.1.113883.3.9143.3.1.3"/> <code code="60593-1" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" codeSystemVersion="2.59" displayName="Medication dispensed.extended Document"> <translation code="60593-1" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="eDispensation"/> </code> <title>Medication dispensed</title> <effectiveTime value="20221130152655+0000"/> <confidentialityCode code="N" codeSystem="2.16.840.1.113883.5.25" codeSystemName="Confidentiality" codeSystemVersion="913-20091020" displayName="normal"/> <languageCode code="en-GB"/> <setId extension="22015711.1" root="2.16.840.1.113883.3.9143.3.1.3"/> <recordTarget> <patientRole classCode="PAT"> <id extension="x1x2x2" root="2.16.840.1.113883.2.25.3.4.1.1.2"/> <addr> <country>GR</country> <streetAddressLine>ΕΓΝΑΤΙΑ 10</streetAddressLine> </addr> <telecom use="H" value="tel:12344"/> <patient> <name> <given>MARINA</given> <family>FILIP</family> </name> <administrativeGenderCode code="F" codeSystem="2.16.840.1.113883.5.1" codeSystemName="AdministrativeGender" codeSystemVersion="913-20091020" displayName="Female"/> <birthTime value="20150101"/> <languageCommunication> <templateId root="1.3.6.1.4.1.19376.1.5.3.1.2.1"/> <languageCode code="en-GB"/> </languageCommunication> </patient> </patientRole> </recordTarget> </ClinicalDocument>
修改代码
String eD = "previous_xml_value"; DocumentBuilder db = null; try { db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException e1) { e1.printStackTrace(); } InputSource is = new InputSource(); is.setCharacterStream(new StringReader(eD)); Document doc = null; try { doc = db.parse(is); } catch (SAXException e1) { e1.printStackTrace(); } // 修改XML内容生成废弃文档 NodeList node_to_change_code_id_title = doc.getElementsByTagName("ClinicalDocument"); Element element_to_change_code_id_title = null; NodeList eD_id_to_set_eD_id = null; Element eD_id_extension = null; NodeList eD_id_to_set_eD_code = null; Element eD_set_code = null; NodeList eD_id_to_set_eD_title = null; Element eD_set_title = null; if (node_to_change_code_id_title.getLength()> 0) { element_to_change_code_id_title = (Element) node_to_change_code_id_title.item(0); eD_id_to_set_eD_id = element_to_change_code_id_title.getElementsByTagName("id"); eD_id_extension = (Element) eD_id_to_set_eD_id.item(0); eD_id_extension.removeAttribute("extension"); eD_id_extension.setAttribute("extension", discard_eD_id_full); eD_id_to_set_eD_code = element_to_change_code_id_title.getElementsByTagName("code"); eD_set_code = (Element) eD_id_to_set_eD_code.item(0); eD_set_code.setAttribute("xmlns", "urn:hl7-org:v3"); // 错误操作 eD_set_code.removeAttribute("code"); eD_set_code.setAttribute("code", "DISCARD-60593-1"); eD_set_code.removeAttribute("codeSystem"); eD_set_code.setAttribute("codeSystem", "2.16.840.1.113883.6.1"); eD_set_code.removeAttribute("codeSystemName"); eD_set_code.setAttribute("codeSystemName", "LOINC"); eD_set_code.removeAttribute("displayName"); eD_set_code.setAttribute("displayName", "Discard Medication Dispensed"); eD_id_to_set_eD_title = element_to_change_code_id_title.getElementsByTagName("title"); eD_set_title = (Element) eD_id_to_set_eD_title.item(0); eD_set_title.setTextContent("Discard Medication Dispensed"); }
生成结果
<ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:pharm="urn:hl7-org:pharm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" classCode="DOCCLIN" moodCode="EVN"> <realmCode xmlns="" code="CY"/> <typeId xmlns="" extension="POCD_HD000040" root="2.16.840.1.113883.1.3"/> <templateId xmlns="" root="1.3.6.1.4.1.12559.11.10.1.3.1.1.2"/> <templateId xmlns="" root="1.3.6.1.4.1.19376.1.5.3.1.1.1"/> <id extension="eDDiscId.CY202303170000002" root="2.16.840.1.113883.3.9143.3.1.3"/> <code code="DISCARD-60593-1" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" codeSystemVersion="2.59" displayName="Discard Medication Dispensed"> <translation xmlns="" code="60593-1" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC" displayName="eDispensation"/> </code> <title xmlns="">Discard Medication Dispensed</title> <effectiveTime xmlns="" value="20221130152655+0000"/> <confidentialityCode xmlns="" code="N" codeSystem="2.16.840.1.113883.5.25" codeSystemName="Confidentiality" codeSystemVersion="913-20091020" displayName="normal"/> <languageCode xmlns="" code="en-GB"/> <setId xmlns="" extension="22015711.1" root="2.16.840.1.113883.3.9143.3.1.3"/> <recordTarget xmlns=""> <patientRole classCode="PAT"> <id extension="x1x2x2" root="2.16.840.1.113883.2.25.3.4.1.1.2"/> <addr> <country>GR</country> <streetAddressLine>ΕΓΝΑΤΙΑ 10</streetAddressLine> </addr> <telecom use="H" value="tel:12344"/> <patient> <name> <given>MARINA</given> <family>FILIP</family> </name> <administrativeGenderCode code="F" codeSystem="2.16.840.1.113883.5.1" codeSystemName="AdministrativeGender" codeSystemVersion="913-20091020" displayName="Female"/> <birthTime value="20150101"/> <languageCommunication> <templateId root="1.3.6.1.4.1.19376.1.5.3.1.2.1"/> <languageCode code="en-GB"/> </languageCommunication> </patient> </patientRole> </recordTarget> </ClinicalDocument>
原因分析
- 命名空间感知未启用:默认的
DocumentBuilderFactory未开启命名空间感知,解析器无法识别XML中的默认命名空间,导致所有元素的命名空间上下文丢失。 - 错误设置命名空间属性:通过
setAttribute("xmlns", "urn:hl7-org:v3")给<code>元素添加命名空间是错误操作——xmlns是特殊的命名空间声明属性,不能用普通setAttribute方法设置,会干扰DOM对命名空间的正确解析,导致元素被强制置于空命名空间。 - 冗余属性操作:先调用
removeAttribute再调用setAttribute完全没必要,setAttribute本身会覆盖原有属性值,冗余操作虽不直接引发问题,但增加了代码复杂度。
解决方案
1. 启用命名空间感知
创建DocumentBuilder时必须开启命名空间感知,确保解析器正确识别XML中的命名空间:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); // 关键:启用命名空间感知 DocumentBuilder db = dbf.newDocumentBuilder();
2. 移除错误的命名空间设置代码
删掉这行错误代码:
eD_set_code.setAttribute("xmlns", "urn:hl7-org:v3");
3. 简化属性修改代码
去掉冗余的removeAttribute调用,直接用setAttribute覆盖原有值:
// 简化id属性修改 eD_id_extension.setAttribute("extension", discard_eD_id_full); // 简化code元素属性修改 eD_set_code.setAttribute("code", "DISCARD-60593-1"); eD_set_code.setAttribute("codeSystem", "2.16.840.1.113883.6.1"); eD_set_code.setAttribute("codeSystemName", "LOINC"); eD_set_code.setAttribute("displayName", "Discard Medication Dispensed");
修正后的完整代码
String eD = "previous_xml_value"; DocumentBuilder db = null; try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); // 启用命名空间感知 db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e1) { e1.printStackTrace(); } InputSource is = new InputSource(); is.setCharacterStream(new StringReader(eD)); Document doc = null; try { doc = db.parse(is); } catch (SAXException | IOException e1) { e1.printStackTrace(); } // 修改XML内容生成废弃文档 NodeList node_to_change_code_id_title = doc.getElementsByTagName("ClinicalDocument"); if (node_to_change_code_id_title.getLength() > 0) { Element element_to_change_code_id_title = (Element) node_to_change_code_id_title.item(0); // 修改id的extension属性 NodeList eD_id_to_set_eD_id = element_to_change_code_id_title.getElementsByTagName("id"); if (eD_id_to_set_eD_id.getLength() > 0) { Element eD_id_extension = (Element) eD_id_to_set_eD_id.item(0); eD_id_extension.setAttribute("extension", discard_eD_id_full); } // 修改code元素的属性 NodeList eD_id_to_set_eD_code = element_to_change_code_id_title.getElementsByTagName("code"); if (eD_id_to_set_eD_code.getLength() > 0) { Element eD_set_code = (Element) eD_id_to_set_eD_code.item(0); eD_set_code.setAttribute("code", "DISCARD-60593-1"); eD_set_code.setAttribute("codeSystem", "2.16.840.1.113883.6.1"); eD_set_code.setAttribute("codeSystemName", "LOINC"); eD_set_code.setAttribute("displayName", "Discard Medication Dispensed"); } // 修改title文本内容 NodeList eD_id_to_set_eD_title = element_to_change_code_id_title.getElementsByTagName("title"); if (eD_id_to_set_eD_title.getLength() > 0) { Element eD_set_title = (Element) eD_id_to_set_eD_title.item(0); eD_set_title.setTextContent("Discard Medication Dispensed"); } }
效果说明
修正后,生成的XML会正确继承根元素的默认命名空间,所有子元素不再出现xmlns=""声明,保持原有的命名空间结构。
内容的提问来源于stack exchange,提问作者zinon
相关产品推荐
相关产品推荐

