XML文件中不可见的差异打破了自制的XML解析器

Invisible differences in XML files - breaking self-made XML parser

本文关键字:XML 文件      更新时间:2023-10-16

我有两个程序与定义良好的XML文件交互。第一个程序(Model)读取它,解析它,并使用文件中的内容来指导模型的运行。第二个程序(控制器)打开并重写XML文件,允许在模型中运行不同的设置。

模型是用C++编写的,在VS2010和VS2012中使用,没有GUI,使用了一个自制的(这是正确的术语吗。控制器是用C#在VS2012中编写的,带有一个GUI,该GUI具有设置XML文件内容的下拉菜单,并使用XmlDocument类读取、编辑和打印XML文件。

突然间,控制器不再吐出可以由Model读取的XML文件。当Model尝试读取XML文件时,它遇到的第一个字符读作"-17"。据我所知,这意味着它无法将其识别为UTF-8字符。这会导致模型出现错误,然后崩溃。较旧的XML文件(看起来与Controller编写的文件完全相同)读起来很好。

以下是文件的示例-请忽略元素中的内容。你们中的一些人可能会说,内容可能导致了问题,但我已经检查了一遍又一遍,它是正确的。如果内容很重要,为什么Model中的解析器在读取XmlDocument创建的文件时会在第一个字符("<"="-17")处失败?

旧文件:

<?xml version="1.0" encoding="UTF-8" ?> 
<Config>
<Mode value="false" Id="Modeflag" />
<Timestep OutputTimestep="Hourly"  CalibrationTimestep="Houry" />
<InitialInput SubCatchmentNumber="1" ModelCalibration="true" SnowSimulation="false" VegSimulation="Method 1" CatchmentNumber="1" FractionalCatchmentArea="1" />
<InputResource Name="All" Location="C:AutoRun_NewestAutoRun" Id="Directory" />
<SimulationScheme SchemeForCatchmentNo="8" Infiltration="true" ChannelRouting="false" Saturation="true" TopographicIndex="true" KDecayWithSoilDepthExp="false" SoilTopoIndex="false" KDecayInPower="true" />
<SnowInput InputCatchmentNumber="1" TempIndexMethod_Hourly="false" RadiationTempIndex_With_SnowInterception="true" EnergyBudgetMethod_With_SnowInterception="false" />
<SnowInputResource Name="All" Location="C:AutoRun_NewestAutoRun" Id="SnowDirectory" />
<OutputDirectory Location="C:AutoRun_NewestInputsOutput_Timestamp_07012015215112" Name="Toronto_Output" />
</Config>

更新的文件:

<?xml version="1.0" encoding="UTF-8" ?>
<Config>
  <Mode value="false" Id="Modeflag" />
  <Timestep OutputTimestep="Hourly" CalibrationTimestep="Hourly" />
  <InitialInput SubCatchmentNumber="1" ModelCalibration="true" SnowSimulation="false" VegSimulation="Method 1" CatchmentNumber="1" FractionalCatchmentArea="1" />
  <InputResource Name="All" Location="C:AutoRun_NewestAutoRun" Id="Directory" />
  <SimulationScheme SchemeForCatchmentNo="8" Infiltration="true" ChannelRouting="false" Saturation="true" TopographicIndex="true" KDecayWithSoilDepthExp="false" SoilTopoIndex="false" KDecayInPower="true" />
  <SnowInput InputCatchmentNumber="1" TempIndexMethod_Hourly="false" RadiationTempIndex_With_SnowInterception="true" EnergyBudgetMethod_With_SnowInterception="false" />
  <SnowInputResource Name="All" Location="C:AutoRun_NewestAutoRun" Id="SnowDirectory" />
  <OutputDirectory Location="C:AutoRun_NewestInputsOutput_Timestamp_07012015215112" Name="Toronto_Output" />
</Config>

添加或删除缩进(C#中XmlDocument类的正确格式)不会改变Model的行为。

这些文件在视觉上完全相同,我看不到任何奇怪的字符或间距。哪些不可见的对象/力量/角色或其他设置可能导致此新错误?

XML文档类是否强制执行了一些对我自制的解析器来说是新的后台编码?

在文件的开头有一个字节顺序标记(BOM)。https://en.wikipedia.org/wiki/Byte_order_mark

BOM是Unicode字符U+FEFF,或UTF-8中的字节0xEF、0xBB、0xBF。如果将0xEF重新解释为带符号字节,则0xEF为-17。如果保存,许多Windows工具尤其会在文件的开头放一个BOM。