Java读取XML文件并导出为CSV格式的技术问题咨询
Java读取非标准XML模板并导出CSV解决方案
问题根因
你遇到的第二行读取报错问题,本质是该文件不是标准XML文件:XML声明(第一行<?xml...?>)和DOCTYPE声明之间不允许存在普通文本节点,第二行的${_INCL:...}是模板占位符,不属于标准XML语法结构,直接用标准XML解析器(DOM/SAX/JAXB等)读取会直接报格式错误。
分步解决方案
第一步:预处理XML文件,兼容非标准行
先按行读取原始文件,单独处理第二行占位符,再将剩余符合XML规范的内容拼接后交给XML解析器处理。如果需要保留第二行的占位符内容,可以单独存储后按需写入CSV。
第二步:解析标准XML段,提取目标字段
解析处理后的XML内容,提取两个核心字段:
- Header字段:拼接SmtpHeaders下所有
<Header>标签的Name和Value属性值 - Body字段:提取
<Body>标签内的全部文本内容(可按需保留换行格式)
第三步:按规则导出CSV
CSV导出时注意转义特殊字符:若字段内容包含逗号、双引号、换行符,需要用双引号将整个字段包裹,内容中原有的双引号要替换为两个连续双引号。
完整代码示例
import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.*; import java.util.List; public class XmlToCsvConverter { public static void main(String[] args) throws IOException, DocumentException { File inputXml = new File("替换为你的XML文件路径"); File outputCsv = new File("替换为你的CSV输出路径"); // 1. 预处理XML,处理第二行非标准内容 BufferedReader reader = new BufferedReader(new FileReader(inputXml)); StringBuilder validXmlContent = new StringBuilder(); String line; int lineNum = 0; // 如需保留第二行占位符可存储该变量,按需写入CSV String secondLinePlaceHolder = ""; while ((line = reader.readLine()) != null) { lineNum++; if (lineNum == 2) { secondLinePlaceHolder = line; continue; } validXmlContent.append(line).append("\n"); } reader.close(); // 2. 解析有效XML内容 SAXReader saxReader = new SAXReader(); // 关闭DTD校验,避免找不到DTD文件报错 saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); Document document = saxReader.read(new ByteArrayInputStream(validXmlContent.toString().getBytes("UTF-8"))); Element root = document.getRootElement(); // 提取Header内容 Element smtpHeaders = root.element("SmtpHeaders"); List<Element> headerList = smtpHeaders.elements("Header"); StringBuilder headerContent = new StringBuilder(); for (Element header : headerList) { String name = header.attributeValue("Name"); String value = header.attributeValue("Value"); headerContent.append(name).append(" & ").append(value); } // 提取Body内容 Element body = root.element("Body"); String bodyContent = body.getText().trim(); // 3. 导出CSV BufferedWriter writer = new BufferedWriter(new FileWriter(outputCsv)); // 写CSV表头 writer.write("Header,Body"); writer.newLine(); // 转义字段内容 String escapedHeader = escapeCsvField(headerContent.toString()); String escapedBody = escapeCsvField(bodyContent); writer.write(escapedHeader + "," + escapedBody); writer.flush(); writer.close(); } // CSV字段转义方法 private static String escapeCsvField(String field) { if (field.contains(",") || field.contains("\"") || field.contains("\n")) { field = "\"" + field.replace("\"", "\"\"") + "\""; } return field; } }
依赖说明
如果使用上述Dom4j解析方案,需要在pom.xml中引入对应依赖:
<dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency>
内容的提问来源于stack exchange,提问作者Abhitosh Kumar
相关产品推荐
相关产品推荐

