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

Posted 林新发

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XmlException: Text node cannot appear in this state. Line 1, position 1(Unity读取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的二进制字节如下:

编码标记
UTF16BE0xfe 0xff
UTF16LE0xff 0xfe
UTF80xef 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相关的技术难题,也欢迎留言或私信~

以上是关于XmlException: Text node cannot appear in this state. Line 1, position 1(Unity读取xml报错,BOM头问题)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

xsd:包含soapUI中的异常:org.apache.xmlbeans.XmlException:org.apache.xmlbeans.XmlException:错误:null之后的文件意外结束(

如果 XmlException.SourceUri 是只读的,那有啥好处?

似乎无法处理 XMLException?

XmlException: '"' 是一个意外的标记。预期的标记是 '"' 或 '''