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

解析,pptx,遇到,异常,十六进制,无效,字符 · 浏览次数 : 29

小编点评

解决方法如下: 1. **捕获XmlException异常**:在加载PPTX文件的时候捕获XmlException类型的异常,并将异常中获取xml内容。 2. **创建ZipArchive对象**:从异常中获取xml内容的路径,然后创建一个ZipArchive对象。 3. **遍历ZipArchive对象**:遍历ZipArchive对象中的所有文件,并判断文件名是否为“.xml”。 4. **处理非“.xml”文件**:如果文件不是“.xml”,创建一个新的entry并将其命名为entry.FullName,然后打开entry.Open(),并尝试读取内容并设置IsInvalidXml属性为false。 5. **处理“.xml”文件**:如果文件是“.xml”,从entry.Open()中读取内容,并使用XDocument.Parse(content)将其解析为XML文档。然后设置IsInvalidXml属性为false。 6. **将非“.xml”文件删除**:如果IsInvalidXml为false,则将该文件从ZipArchive中删除。 7. **将“.xml”文件写入新文件**:如果所有文件处理完成,将所有“非”.xml”文件添加到一个新的XML文件中。 8. **返回新文件中包含的XML数据**:返回新文件中包含的XML数据。

正文

问题描述:

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


原因分析:

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

string r = "[\x00-\x08\x0B\x0C\x0E-\x1F\x26]";
return Regex.Replace(brokenXml, r, "", RegexOptions.Compiled);

 


解决方案:

原因和处理方式都有了,那么问题来了,加载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); } } } } } }

与解析PPTX 遇到异常:“\b”(十六进制值 0x08)是无效的字符。相似的内容:

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

问题描述: 通过DocumentFormat.OpenXml解析PPTX文件时遇到异常:“\b”(十六进制值 0x08)是无效的字符,查看文件发现存在乱码,乱码的十六进制值刚好时异常中提到的0x08 原因分析: 网上有很多关于这类xml遇到无效字符异常的文章,其原因是xml中包含了不可打印的控制字符

C# 使用openxml解析PPTX中的文本内容

前言 本文讨论的仅针对微软Office 2007以后的(OOXML定义)PowerPoint文档,Office 2007以前的用二进制格式定义的(ppt格式)文档不在本文讨论范围。 一、依赖类库 本文需要依赖两个免费的第三方类库:DocumentFormat.OpenXml和FreeSpire.Do

解析QAnything启动命令过程

一.启动命令过程日志 启动命令bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat。输入日志如下所示: root@MM-202203161213:/mnt/l/20230918_RAG方向/QAnything# bas

解析Html Canvas的卓越性能与高效渲染策略

一、什么是Canvas 想必学习前端的同学们对Canvas 都不陌生,它是 HTML5 新增的“画布”元素,可以使用JavaScript来绘制图形。 Canvas元素是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitma

[转帖]解析Linux gcore: 揭示程序内存捕获的秘密(linuxgcore)

https://www.dbs724.com/133618.html Linux gcore 是一种在Linux系统中使用命令行工具捕获进程内存内容的方法。它允许程序员制定程序的一个内存快照,从而帮助他们了解在特定时刻,程序的内部状态是什么状态。 通过生成一个进程的Core文件(也称为“内存快照”或

解析类型参数

原文在这里。 由 Ian Lance Taylor 发布于2023年9月26日 slices 包函数签名 slices.Clone 函数很简单:它返回一个任意类型切片的副本: func Clone[S ~[]E, E any](s S) S { return append(s[:0:0], s...

解析用户消费记录(数据分析三剑客综合使用)

博客地址:https://www.cnblogs.com/zylyehuo/ 开发环境 anaconda 集成环境:集成好了数据分析和机器学习中所需要的全部环境 安装目录不可以有中文和特殊符号 jupyter anaconda提供的一个基于浏览器的可视化开发工具 import numpy as np

解析关于Tomcat Servlet-request的获取请求参数及几种常用方法

摘要:本文主要讲解Tomcat之Servlet-request请求参数、Servlet转发机制、常用方法 本文分享自华为云社区《浅谈Tomcat之Servlet-request获取请求参数及常用方法》,作者:QGS。 //获取Map集合中所有的key Enumeration getP

解析Spring内置作用域及其在实践中的应用

摘要:本文详细解析了Spring的内置作用域,包括Singleton、Prototype、Request、Session、Application和WebSocket作用域,并通过实例讲解了它们在实际开发中的应用。 本文分享自华为云社区《Spring高手之路4——深度解析Spring内置作用域及其在实

解析BeanDefinitionRegistry与BeanDefinition合并

本文深入探讨Spring的BeanDefinition和BeanDefinitionRegistry,详细介绍了BeanDefinition的合并过程及其源码分析,揭示了Spring配置元数据的内在逻辑。