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

Java中保留XML结构替换属性特殊字符的实现方案

问题

我需要处理XML内容,要求遍历所有节点(节点和属性名称都不固定),只对属性值应用正则替换(保留A-Za-z0-9#&',-.这些字符,其余删掉),然后重建XML。直接对XML字符串用正则的方法行不通,会误删节点名里的冒号(比如<XYZ:CompanyCd>里的冒号),之前试的字符串转义+正则替换完全没用,求Java里的可行实现方案。

XML样本:

<AccountNumberId>JY00000830</AccountNumberId>
<XYZ:CompanyCd>DOC</XYZ:CompanyCd>
<XYZ:MultiPolicyDiscountCd>0</XYZ:MultiPolicyDiscountCd>
<QuestionAnswer>
<QuestionCd>XYZ:1</QuestionCd>
<YesNoCd>No</YesNoCd>
</QuestionAnswer>
<TransactionSeqNumber/>
<PersApplicationInfo>
<ApplicationWrittenDt>2023-02-26</ApplicationWrittenDt>
<KnownSinceDt>2007-02-05</KnownSinceDt>
</PersApplicationInfo>
<XYZ:TaxExemptionInd>0</XYZ:TaxExemptionInd>
</PersPolicy>
<Location id="LOC-1">
<ItemIdInfo>
<XYZ:FixedId>8001</XYZ:FixedId>
</ItemIdInfo>
<Addr>
<Addr1>`**`1234 $$$RIVERWOOD !!<GATE SUITE> 136`**`</Addr1>
...

之前尝试的无效代码:

var escapedXml = StringEscapeUtils.escapeXml(xmlString);
var replaceSplChars = escapedXml
  .replaceAll("[^A-Za-z0-9#&',-.\n<>]", "")
  .replace("\t", "");
var toXML = StringEscapeUtils.unescapeXml(replaceSplChars);
Java实现方案

用Java标准库的DOM解析来处理,精准遍历每个元素的属性,只修改属性值,不会破坏节点名或文本内容,完美解决正则误改XML结构的问题。

1. 编写属性值清理工具方法

先封装一个专门过滤属性值的方法,按要求保留指定字符:

private static String cleanAttrValue(String value) {
    if (value == null) return null;
    // 仅保留允许的字符,其余全部移除
    return value.replaceAll("[^A-Za-z0-9#&',-.]", "");
}

2. 遍历XML节点处理属性

通过DOM解析XML,递归遍历所有元素节点,逐个处理属性值:

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringReader;
import java.io.StringWriter;

public class XmlAttrCleaner {

    public static String processXml(String rawXml) throws Exception {
        // 初始化DOM解析器,开启命名空间支持(兼容XYZ:这类带前缀的节点)
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(rawXml)));

        // 递归遍历所有节点,清理属性值
        traverseNodes(doc.getDocumentElement());

        // 将修改后的Document转换回XML字符串
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        // 不需要XML声明则保留此行,需要则删除
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        // 可选:设置输出缩进,提升可读性
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        
        DOMSource source = new DOMSource(doc);
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);

        return writer.toString();
    }

    private static void traverseNodes(Node node) {
        // 仅处理元素节点
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            NamedNodeMap attrs = element.getAttributes();
            // 遍历当前元素的所有属性
            for (int i = 0; i < attrs.getLength(); i++) {
                Attr attr = (Attr) attrs.item(i);
                String cleanedValue = cleanAttrValue(attr.getValue());
                attr.setValue(cleanedValue);
            }
        }
        // 递归处理子节点,覆盖所有层级
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            traverseNodes(childNodes.item(i));
        }
    }

    private static String cleanAttrValue(String value) {
        if (value == null) return null;
        return value.replaceAll("[^A-Za-z0-9#&',-.]", "");
    }
}

3. 使用示例

直接调用工具类处理你的XML字符串:

public static void main(String[] args) {
    try {
        String originalXml = "你的XML内容";
        String processedXml = XmlAttrCleaner.processXml(originalXml);
        System.out.println(processedXml);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关键说明

  • 开启setNamespaceAware(true),确保带命名空间前缀的节点(如XYZ:)能被正常解析,原有XML结构完全保留。
  • 仅对属性值执行正则替换,节点名称、文本内容均不修改,彻底解决字符串正则误删冒号的问题。
  • 递归遍历所有节点,无论节点或属性名称是否固定,都能全覆盖处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:27:59