XML文件中的隐形差异 - 打破自制的XML解析器

时间:2015-07-02 04:14:48

标签: c# c++ xml visual-studio-2012

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

模型是用C ++编写的,在VS2010和VS2012中使用过,没有GUI,并且使用自制的(这是正确的术语吗?)XML解析器已经工作多年没有失败 - 我刚检查了SVN对于构成它的文件的修订 - 自2013年以来没有任何内容。控制器是在VS2012中用C#编写的,其GUI具有设置XML文件内容的下拉列表,并使用XmlDocument class读入,编辑和打印XML文件。

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

以下是文件示例 - 请忽略元素内的内容。有些人可能会说内容可能会导致问题,但我一次又一次地检查它,这是正确的。如果内容很重要,为什么在读取XmlDocument创建的文件时,Model中的解析器会在第一个字符('<'='-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_Newest\AutoRun" 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_Newest\AutoRun" Id="SnowDirectory" />
<OutputDirectory Location="C:\AutoRun_Newest\Inputs\Output_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_Newest\AutoRun" 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_Newest\AutoRun" Id="SnowDirectory" />
  <OutputDirectory Location="C:\AutoRun_Newest\Inputs\Output_Timestamp_07012015215112" Name="Toronto_Output" />
</Config>

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

这些文件在视觉上是相同的,我看不到奇怪的字符或间距。什么不可见的物体/力量/字符或其他设置可能导致这个新的错误?

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

1 个答案:

答案 0 :(得分:1)

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

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