解析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配置元数据的内在逻辑。