使用sgml npm库解析OFX文件遇报错,求解决方案
解决sgml库解析OFX文件时的"content must start with document element"错误
问题概述
尝试使用npm的sgml库解析OFX v1至v1.6版本的SGML格式数据,计划先将其转换为标准XML,再通过xml2json转为JSON对象,但运行代码时抛出错误:content must start with document element when document type isn't specified,调试发现解析部分标签后触发该错误。
错误原因
OFX的SGML文件开头包含非SGML格式的头部信息(比如OFXHEADER:100、DATA:OFXSGML等行),这些内容不属于SGML文档元素范畴。sgml库在未指定DOCTYPE的情况下,要求内容必须以文档根元素开头,直接解析完整文件会触发该错误。
解决方案
- 预处理OFX文件内容,剥离头部信息,只保留从
<OFX>标签开始的SGML主体部分 - 修改代码,在将内容传入解析器前完成过滤处理
修改后的完整代码
const sgml = require('sgml'); const fs = require('fs').promises; const Stream = require('stream'); async function parseOFX() { var entitymanager = new sgml.NoopEntitymanager(); var errorhandler = new sgml.Errorhandler(); var resolver = new sgml.Resolver(); var parser = new sgml.Parser(); // 初始化Readable流时添加空read方法,避免未实现报错 const readableStream = new Stream.Readable({ read() {} }); let outputhandler = new sgml.Outputhandler(readableStream, entitymanager); outputhandler.output_format = "xml"; parser.documentHandler = outputhandler; parser.dtdHandler = outputhandler; parser.errorHandler = errorhandler; parser.lexicalHandler = outputhandler; parser.entityResolver = resolver ; let recordmanager = new sgml.PlatformStringRecordmanager(errorhandler, parser); let fileData = await fs.readFile("MY FILE PATH"); // 预处理:提取<OFX>标签开始的有效SGML内容 const contentStr = fileData.toString(); const ofxStartIndex = contentStr.indexOf('<OFX>'); if (ofxStartIndex === -1) { throw new Error("文件中未找到<OFX>标签"); } const validSGMLContent = contentStr.slice(ofxStartIndex); recordmanager.set_input(validSGMLContent); parser.recordManager = recordmanager; recordmanager.start_records(); // 收集并打印转换后的XML内容(可根据需求调整处理逻辑) readableStream.on('data', (chunk) => { console.log('转换后的XML片段:', chunk.toString()); }); } parseOFX().catch(err => console.error(err));
补充说明
- 预处理步骤通过
indexOf('<OFX>')定位SGML主体起始位置,若文件中标签为小写<ofx>,需对应调整匹配字符串 - 初始化
Stream.Readable时必须添加空的read方法,否则会触发"not implemented"运行时错误 - 转换后的XML可直接传入xml2json库处理为JSON对象
内容的提问来源于stack exchange,提问作者Dennip
相关产品推荐
相关产品推荐

