解析pptx 遇到异常:“\b”(十六进制值 0x08)是无效的字符。-kb88凯时官网登录

来自:
时间:2024-01-31
阅读:

问题描述:

通过documentformat.openxml解析pptx文件时遇到异常:“\b”(十六进制值 0x08)是无效的字符,查看文件发现存在乱码,乱码的十六进制值刚好时异常中提到的0x08

解析pptx 遇到异常:“\b”(十六进制值 0x08)是无效的字符。


原因分析:

网上有很多关于这类xml遇到无效字符异常的文章,其原因是xml中包含了不可打印的控制字符,解决办法是正则匹配替换这类字符。正则匹配的代码如下:

string r = "[\x00-\x08\x0b\x0c\x0e-\x1f\x26]";
return regex.replace(brokenxml, r, "", regexoptions.compiled);

 


kb88凯时官网登录的解决方案:

原因和处理方式都有了,那么问题来了,加载pptx文件的时候就抛出异常了,在什么时候替换xml中的控制字符呢?想起openxmlpowertools的源码中关于处理文档中包含不合法的uri的代码,于是如法炮制,在加载页面slide的时候捕获xmlexception类型的异常,在异常中修复xml内容

try
{
    .......
}
catch (xmlexception xe)
{
	using (filestream fs = new filestream(filepath, filemode.openorcreate, fileaccess.readwrite))
	{
		xmlfixer.fixinvalidxml(fs, brokenxml =>
		{
			string r = "[\x00-\x08\x0b\x0c\x0e-\x1f\x26]";
			return regex.replace(brokenxml, r, "", regexoptions.compiled);
		});
	}
	return readpptxtext(filepath);
}

public static class xmlfixer { public static void fixinvalidxml(stream fs,func invalidxmlhandler) { using (ziparchive za = new ziparchive(fs, ziparchivemode.update)) { bool isinvalidxml = false; for (int i=0;i< za.entries.count;i ) { var entry = za.entries[i]; if (!entry.name.endswith(".xml")) continue; bool replaceentry = false; xdocument entryxdoc = null; using (var entrystream = entry.open()) { try { if (isinvalidxml) { string content; using (streamreader sr = new streamreader(entrystream)) { content = invalidxmlhandler(sr.readtoend()); } entryxdoc = xdocument.parse(content); isinvalidxml = false; replaceentry = true; } else { entryxdoc = xdocument.load(entrystream); isinvalidxml = false; } } catch (xmlexception xex) { i--; isinvalidxml = true; } } if (replaceentry) { var fullname = entry.fullname; entry.delete(); var newentry = za.createentry(fullname); using (streamwriter writer = new streamwriter(newentry.open())) using (xmlwriter xmlwriter = xmlwriter.create(writer)) { entryxdoc.writeto(xmlwriter); } } } } } }
返回顶部
顶部
网站地图