我有很多具有相同结构的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标签,因为它在 i 标签的位置上抱怨这一行
<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无法反序列化它?是否可以在不更改文档的情况下获得解决方法?
答案 0 :(得分:1)
当你指向内部HTML标签时,你是对的。 您的XML无效,因为您在简单(文本)元素中包含标记。 XmlSerializer不理解并抛出错误。
如果您已生成XML文件,那么 可以预先删除简单元素中的数据:
mipmap
)答案 1 :(得分:0)
尝试序列化导致问题的实例。然后,您可以将序列化的输出与您尝试反序列化的文件的内容进行比较。两个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轻松查看这两个文件之间的区别。
答案 2 :(得分:0)
假设我们有以下类:
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
活动。
在事件处理程序中手动将我们的属性设置为数据。
private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
var foo = (Foo)e.ObjectBeingDeserialized;
foo.Text = e.Element.InnerXml;
}
请注意,属性名称不应与xml节点名称匹配(区分大小写)。仅在此情况下触发事件。如果名称匹配,请使用XmlIgnore
属性。