微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XmlException: Text node cannot appear in this state. Line 1, position 1Unity读取xml报错,BOM头问题

一、前言

点关注不迷路,持续输出Unity干货文章
嗨,大家好,我是新发。
Unity项目开中,我们读取XML配置表时,如果XML的编码格式是UTF-8 带BOM头的话,在移动端解析XML会报错:

XmlException: Text node cannot appear in this state.  Line 1,position 1

特别是多人协作的项目,大家使用的文本编辑器不同,可能其他人就不小心把文件编码修改了,导致出现BOM头。
那么,我们有没有办法解决这个问题呢?今天就教一下大家吧。

二、什么是BOM头

BOM是用来判断文本文件是哪一种Unicode编码的标记,其本身是一个Unicode字符("\uFEFF"),位于文本文件头部。
在不同的Unicode编码中,对应的BOM的二进制字节如下:

编码 标记
UTF16BE 0xfe 0xff
UTF16LE 0xff 0xfe
UTF8 0xef 0xbb 0xbf

我们可以根据文件头部的几个字节和上面的表格对应来判断该文件是哪种编码形式。
UTF-8编码文件中,BOM文件头部占用三个字节,现在已经有很多软件识别BOM头,但是还有些不能识别,比如PHP就不能识别BOM头。

三、如何查看文件的编码格式

可以使用Notpad++打开文本文件,点击菜单编码(N)即可查看当前文件的编码格式。

Notpad++官网:https://notepad.plus/

在这里插入图片描述


我们也可以使用HexEditor来查看文件头部标识符,首先,我们先在Notepad++中将编码转为UTF-8-BOM编码,然后保存。

在这里插入图片描述


我们在这里看不到0xef 0xbb 0xbf这个BOM头标识符。

在这里插入图片描述


这个时候,HexEditor登场,在HexEditor中我们看到了这个BOM头啦。

HexEditor下载地址:https://hexeditor.en.softonic.com/

在这里插入图片描述

四、Unity C#如何检测配置表含有BOM头

我们可以在Unity中做个工具,批量检测配置表是否还有BOM头。如下,其中cfg1.bytesUTF-8 编码cfg2.bytesUTF-8-BOM 编码

在这里插入图片描述


CfgBomCheckTools.cs代码如下:

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

public class CfgBomCheckTools
{
    [MenuItem("Gametools/检测并修复配置表BOM头")]
    public static void CheckcfgBom()
    {
        CheckAndFixBom(GetConfigFiles());
    }

    //获取目录中的所有配置表文件,.bytes结尾的文件内容其实是xml
    static string[] GetConfigFiles()
    {
        string dir_name = Application.dataPath + "/ConfigDir/";
        return System.IO.Directory.GetFiles(dir_name, "*.bytes", SearchOption.AllDirectories);
    }

    /// <summary>
    /// 检测并修复Bom头
    /// </summary>
    /// <param name="files"></param>
    static void CheckAndFixBom(string[] files)
    {
        foreach (var f in files)
        {
            bool hasBom = false;
            byte[] bs = File.ReadAllBytes(f);
            if (3 <= bs.Length && bs[0] == 0xef && bs[1] == 0xbb && bs[2] == 0xbf)
            {
                hasBom = true;
            }
            if(hasBom)
            {
                var ms = new MemoryStream(bs, 3, bs.Length - 3);
                File.WriteallBytes(f, ms.ToArray());
                Debug.LogError(string.Format("配置表有BOM头,自动修复之:{0}", f));
            }
        }
    }
}

点击菜单Gametools/检测配置表BOM头

在这里插入图片描述


输出结果如下,可以正常检测出来结果。

在这里插入图片描述


我们再使用HexEditor打开cfg2.bytes看下是否真的没有BOM头了,如下,没有BOM头了,说明修复成功了。

在这里插入图片描述

五、结束语

完毕。
喜欢Unity的同学,不要忘记点击关注,如果有什么Unity相关的技术难题,也欢迎留言或私信~

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐