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

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

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

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

突然之间,Controller 不再吐出 Model 可以读取的 XML 文件了。当模型尝试读取 XML 文件时,它遇到的第一个字符读作“-17”。据我所知,这意味着它无法将其识别为 UTF-8 字符。这导致模型计算出错误然后崩溃。较旧的 XML 文件(看起来与 Controller 编写的文件相同)读起来没问题。

以下是文件示例 - 请忽略元素中的内容。可能有人会说可能是内容问题,但我反复核对过,是对的。如果内容很重要,为什么模型中的解析器在读取 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_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 类进行适当的格式化)不会改变模型的行为。

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

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

最佳答案

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

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

关于c# - XML文件中的隐形差异——破解自制XML解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31175493/

相关文章:

c++ - OpenCV如何平滑边界

java - sonar-maven-plugin fails because of invalid checkstyle.xml (The processing instruction target matching "[xX][mM][lL]"is not allowed)

html - 使用 FOR XML PATH 在 SQL Server 中格式化颜色

java - 使用 xmlstream 读取器时出错

c# - 组合框 C# 中没有显示任何内容

c# - C# 中的图像 URL 验证

c# - WP8 : Fast app resume + secondary tile + MainPage = 2 instances

c# - 用c++或C#实时录制声音

c# - HttpContext.Cache - 每个请求还是每个应用程序域?

c++ - 是否可以使用 CRTP 访问父类主体内的成员?