XML反序列化c#给出有效文档的错误
本文关键字:文档 错误 有效 反序列化 XML | 更新日期: 2023-09-27 18:07:31
我有很多具有相同结构的XML文件。他们中的许多工作正常,但对于一些XmlSerializer给了我一个错误,但当我把文档在xml验证器-它说文档是正确的。
反序列化代码:
var document = serializer.Deserialize(File.OpenRead(file));
错误:
System.InvalidOperationException: There is an error in XML document (504, 8). ---> System.Xml.XmlException: Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 504, position 8.
at System.Xml.XmlReader.ReadElementString()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read33_Claimtext(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read34_Claim(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read35_Claims(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read43_Patentdocument(Boolean isNullable, Boolean checkType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderPatentdocument.Read44_patentdocument()
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
给出错误的文档部分:
<text>12. Führungsschiene nach einem der Ansprüche 2 bis 11, dadurch gekennzeichnet, daß in den beiden Nutwänden (<b>11<i>a</i>, 11</b><i>a′)</i> einander gegenüberliegende Bohrungen (<b>14</b><i>a</i>, <b>14</b><i>a</i>′) vorgesehen sind, von denen die eine Bohrung (<b>14</b><i>a</i>′) durch das Einsatzteil (<b>15</b><i>a)</i> verschlossen ist.</text>
我想这是因为内联html标签在里面因为它抱怨这一行在的位置我标签
<b>11<i>a</i>, 11</b>
但是例如,根据XmlSerializer,这个xml是正确的,并且可以反序列化它:
<text>9. Führungsschiene nach Anspruch 8, dadurch gekennzeichnet, daß der Ansatz (<b>20</b>) die Zuführfläche (<b>25</b>) aufweist.</text>
所以我的问题是为什么xml验证器说文档是有效的,而XmlSerializer不能反序列化它?是否有可能在不更改文档的情况下找到解决方案?
当您指向内部HTML标记时,您是对的。您的XML无效,因为您在一个简单的(文本)元素中有标记。XmlSerializer无法理解并抛出错误。
如果您已经生成了XML文件,那么可以预先转义简单元素中的数据:
- 与HTML编码
- 或者将其封装在CDATA标签(
<![CDATA[...]]>
)
尝试序列化导致问题的实例。然后,可以将序列化的输出与试图反序列化的文件的内容进行比较。这两个XML字符串之间的差异将告诉您问题出在哪里。
下面是一个将类实例序列化为XML的快速函数:
public static string Serialize<T>(T entity)
{
if (entity == null)
return String.Empty;
try
{
XmlSerializer XS = new XmlSerializer(typeof(T));
System.IO.StringWriter SW = new System.IO.StringWriter();
XS.Serialize(SW, entity);
return SW.ToString();
}
catch (Exception e)
{
Logging.Log(Severity.Error, "Unable to serialize entity", e);
return String.Empty;
}
}
如果你还没有尝试过,我建议你使用BeyondCompare软件来轻松查看两个文件之间的差异。
假设我们有以下类:
public class Foo
{
//[XmlIgnore]
public string Text { get; set; }
}
和以下格式的xml:
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<text>12. Führungsschiene nach einem der Ansprüche 2 bis 11, dadurch gekennzeichnet, daß in den beiden Nutwänden (<b>11<i>a</i>, 11</b><i>a′)</i> einander gegenüberliegende Bohrungen (<b>14</b><i>a</i>, <b>14</b><i>a</i>′) vorgesehen sind, von denen die eine Bohrung (<b>14</b><i>a</i>′) durch das Einsatzteil (<b>15</b><i>a)</i> verschlossen ist.</text>
</Foo>
那么我们可以对数据进行如下反序列化。
var xs = new XmlSerializer(typeof(Foo));
xs.UnknownElement += Xs_UnknownElement;
Foo foo;
using (var fs = new FileStream("test.txt", FileMode.Open))
{
foo = (Foo)xs.Deserialize(fs);
}
订阅XmlSerializer
到UnknownElement
事件
在事件处理程序中手动设置我们的属性为data
private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
var foo = (Foo)e.ObjectBeingDeserialized;
foo.Text = e.Element.InnerXml;
}
请注意,属性名不应该匹配xml节点名(区分大小写)。只有在这种情况下才触发事件。如果名称匹配,则使用XmlIgnore
属性。