XML 反序列化错误 - 意外 'EndElement'
XML Deserialization Error - unexpected 'EndElement'
编辑:如果有人来这里寻找解决方案 - 下面的代码已经更新,现在可以正常工作,这要归功于接受的答案
使用面向 .NET 4.5.3 的 C#,我正在尝试反序列化 Web API REST XML 对 C# class 实例的响应。
我的问题是:如何修复此代码,使其执行预期的操作 - 正确反序列化 XML 对 C# class 实例的响应。
由于我在属性中添加了'IsRequired = true',所以抛出异常:
Message: Error in line 1 position 226. 'EndElement' 'matchset' from namespace 'urn:expasy:scanprosite' is not expected. Expecting element 'n_match'.
Source: System.Runtime.Serialization
StackTrace:
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, Int32 memberIndex, Int32 requiredIndex, XmlDictionaryString[] memberNames)
at ReadmatchsetFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
at System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpContentExtensions.<ReadAsAsyncCore>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at ConsoleApplication4.Prosite.<XmlDeserialize>d__1.MoveNext() in C:\Users\Aaron\Documents\Visual Studio 14\Projects\ConsoleApplication4\ConsoleApplication4\Prosite.cs:line 22
这是程序到控制台的输出 window(没有设置 IsRequired):
n_match:
n_seq:
matchset.match.length: 0
这里是HTTP请求和反序列化代码:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
public static class Prosite
{
public static async Task<string> GetPrositeXML()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.expasy.org/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("cgi-bin/prosite/PSScan.cgi?seq=ENTK_HUMAN&output=xml");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();//AsAsync<matchset>();
}
}
return null;
}
}
}
这里是控制台应用程序代码:
using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
var matchsetTask = Prosite.GetPrositeXML();
var xmlString = matchsetTask.Result;
var matchset = xmlString.LoadFromXML<matchset>();
if (matchset != null)
{
Console.WriteLine("n_match: " + matchset.n_match);
Console.WriteLine("n_seq: " + matchset.n_seq);
Console.WriteLine("matchset.match.length: " + matchset.match.Length);
foreach (var match in matchset.match)
{
Console.WriteLine("level: " + match.level);
Console.WriteLine("level_tag: " + match.level_tag);
Console.WriteLine("score: " + match.score);
Console.WriteLine("sequence_ac: " + match.sequence_ac);
Console.WriteLine("sequence_db: " + match.sequence_db);
Console.WriteLine("sequence_id: " + match.sequence_id);
Console.WriteLine("signature_ac: " + match.signature_ac);
Console.WriteLine("signature_id: " + match.signature_id);
Console.WriteLine("start: " + match.start);
Console.WriteLine("stop: " + match.stop);
Console.WriteLine("");
}
}
Console.ReadKey();
}
}
}
这是根节点 'matchset' 模型的 class:
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.ServiceModel;
namespace ConsoleApplication4
{
[Serializable]
[XmlSerializerFormat]
[DataContract(Name = "matchset", Namespace = "urn:expasy:scanprosite")]
[XmlRoot(ElementName = "matchset", Namespace = "urn:expasy:scanprosite")]
public class matchset
{
[DataMember(Name = "match")]
[XmlElement("match")]
public match[] match;
[DataMember(Name = "n_match", IsRequired = true)]
[XmlAttribute("n_match")]
public string n_match;
[DataMember(Name = "n_seq", IsRequired = true)]
[XmlAttribute("n_seq")]
public string n_seq;
}
}
这里是 'match' 模型的代码:
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.ServiceModel;
namespace ConsoleApplication4
{
[Serializable]
[XmlSerializerFormat]
[DataContract(Name = "match", Namespace = "")]
public class match
{
[DataMember(Name = "sequence_ac")]
[XmlElement("sequence_ac")]
public string sequence_ac;
[DataMember(Name = "sequence_id")]
[XmlElement("sequence_id")]
public string sequence_id;
[DataMember(Name = "sequence_db")]
[XmlElement("sequence_db")]
public string sequence_db;
[DataMember(Name = "start")]
[XmlElement("start")]
public string start;
[DataMember(Name = "stop")]
[XmlElement("stop")]
public string stop;
[DataMember(Name = "signature_ac")]
[XmlElement("signature_ac")]
public string signature_ac;
[DataMember(Name = "signature_id")]
[XmlElement("signature_id")]
public string signature_id;
[DataMember(Name = "level_tag")]
[XmlElement("level_tag")]
public string level_tag;
[DataMember(Name = "score")]
[XmlElement("score")]
public string score;
[DataMember(Name = "level")]
[XmlElement("level")]
public string level;
}
}
这是正在反序列化的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<matchset xmlns="urn:expasy:scanprosite" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:expasy:scanprosite http://expasy.org/tools/scanprosite/scanprosite.xsd" n_match="13" n_seq="1">
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>54</start>
<stop>169</stop>
<signature_ac>PS50024</signature_ac>
<signature_id>SEA</signature_id>
<score>32.979</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>183</start>
<stop>222</stop>
<signature_ac>PS50068</signature_ac>
<signature_id>LDLRA_2</signature_id>
<score>10.75</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>197</start>
<stop>221</stop>
<signature_ac>PS01209</signature_ac>
<signature_id>LDLRA_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>225</start>
<stop>334</stop>
<signature_ac>PS01180</signature_ac>
<signature_id>CUB</signature_id>
<score>13.293</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>345</start>
<stop>504</stop>
<signature_ac>PS50060</signature_ac>
<signature_id>MAM_2</signature_id>
<score>42.203</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>391</start>
<stop>431</stop>
<signature_ac>PS00740</signature_ac>
<signature_id>MAM_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>524</start>
<stop>634</stop>
<signature_ac>PS01180</signature_ac>
<signature_id>CUB</signature_id>
<score>17.206</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>642</start>
<stop>678</stop>
<signature_ac>PS50068</signature_ac>
<signature_id>LDLRA_2</signature_id>
<score>13.3</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>655</start>
<stop>677</stop>
<signature_ac>PS01209</signature_ac>
<signature_id>LDLRA_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>678</start>
<stop>788</stop>
<signature_ac>PS50287</signature_ac>
<signature_id>SRCR_2</signature_id>
<score>16.02</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>785</start>
<stop>1019</stop>
<signature_ac>PS50240</signature_ac>
<signature_id>TRYPSIN_DOM</signature_id>
<score>39.104</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>821</start>
<stop>826</stop>
<signature_ac>PS00134</signature_ac>
<signature_id>TRYPSIN_HIS</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>965</start>
<stop>976</stop>
<signature_ac>PS00135</signature_ac>
<signature_id>TRYPSIN_SER</signature_id>
<level_tag>(0)</level_tag>
</match>
</matchset>
XmlSerializationHelper class 由@dbc 在接受的答案中提供:
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication4
{
public static class XmlSerializationHelper
{
public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
{
using (var textWriter = new StringWriter())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // For cosmetic purposes.
settings.IndentChars = " "; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
{
if (omitStandardNamespaces)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
serializer.Serialize(xmlWriter, obj, ns);
}
else
{
serializer.Serialize(xmlWriter, obj);
}
}
return textWriter.ToString();
}
}
public static string GetXml<T>(this T obj, XmlSerializer serializer)
{
return GetXml(obj, serializer, false);
}
public static string GetXml<T>(this T obj, bool omitNamespace)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
return GetXml(obj, serializer, omitNamespace);
}
public static string GetXml<T>(this T obj)
{
return GetXml(obj, false);
}
public static T LoadFromXML<T>(this string xmlString)
{
return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
}
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
{
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = serial.Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
}
}
谢谢。
您的 类 包含数据协定属性和 XmlSerializer
属性的混合。由于属性 [XmlSerializerFormat]
的应用,我假设您正在使用 XmlSerializer
。在这种情况下,您需要:
将 XmlRoot
属性放回 matchset
:
[Serializable]
[XmlSerializerFormat]
[DataContract(Name = "matchset", Namespace = "urn:expasy:scanprosite")]
[XmlRoot(ElementName = "matchset", Namespace = "urn:expasy:scanprosite")]
public class matchset
{
将public match[] match
改为XmlElement
:
[DataMember(Name = "match")]
[XmlElement("match")]
public match[] match
{
get { return this.matchField; }
set { this.matchField = value; }
}
这样做之后,我能够读取您 post 中给出的 xml 字符串。
答案基于您的原始 类,而非您修改后的 类。以下是我的测试方式:
public static class TestMatchSet
{
public static void Test()
{
var xml = XmlProvider.GetXml(); // Returns the long XML string from the post.
var matchSet = XmlSerializationHelper.LoadFromXML<matchset>(xml);
Debug.WriteLine(matchSet.GetXml());
}
}
public static class XmlSerializationHelper
{
public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
{
using (var textWriter = new StringWriter())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // For cosmetic purposes.
settings.IndentChars = " "; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
{
if (omitStandardNamespaces)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
serializer.Serialize(xmlWriter, obj, ns);
}
else
{
serializer.Serialize(xmlWriter, obj);
}
}
return textWriter.ToString();
}
}
public static string GetXml<T>(this T obj, XmlSerializer serializer)
{
return GetXml(obj, serializer, false);
}
public static string GetXml<T>(this T obj, bool omitNamespace)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
return GetXml(obj, serializer, omitNamespace);
}
public static string GetXml<T>(this T obj)
{
return GetXml(obj, false);
}
public static T LoadFromXML<T>(this string xmlString)
{
return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
}
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
{
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = serial.Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
}
编辑:如果有人来这里寻找解决方案 - 下面的代码已经更新,现在可以正常工作,这要归功于接受的答案
使用面向 .NET 4.5.3 的 C#,我正在尝试反序列化 Web API REST XML 对 C# class 实例的响应。
我的问题是:如何修复此代码,使其执行预期的操作 - 正确反序列化 XML 对 C# class 实例的响应。
由于我在属性中添加了'IsRequired = true',所以抛出异常:
Message: Error in line 1 position 226. 'EndElement' 'matchset' from namespace 'urn:expasy:scanprosite' is not expected. Expecting element 'n_match'.
Source: System.Runtime.Serialization
StackTrace:
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, Int32 memberIndex, Int32 requiredIndex, XmlDictionaryString[] memberNames)
at ReadmatchsetFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
at System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlReader reader)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpContentExtensions.<ReadAsAsyncCore>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at ConsoleApplication4.Prosite.<XmlDeserialize>d__1.MoveNext() in C:\Users\Aaron\Documents\Visual Studio 14\Projects\ConsoleApplication4\ConsoleApplication4\Prosite.cs:line 22
这是程序到控制台的输出 window(没有设置 IsRequired):
n_match:
n_seq:
matchset.match.length: 0
这里是HTTP请求和反序列化代码:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
public static class Prosite
{
public static async Task<string> GetPrositeXML()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.expasy.org/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("cgi-bin/prosite/PSScan.cgi?seq=ENTK_HUMAN&output=xml");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();//AsAsync<matchset>();
}
}
return null;
}
}
}
这里是控制台应用程序代码:
using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
var matchsetTask = Prosite.GetPrositeXML();
var xmlString = matchsetTask.Result;
var matchset = xmlString.LoadFromXML<matchset>();
if (matchset != null)
{
Console.WriteLine("n_match: " + matchset.n_match);
Console.WriteLine("n_seq: " + matchset.n_seq);
Console.WriteLine("matchset.match.length: " + matchset.match.Length);
foreach (var match in matchset.match)
{
Console.WriteLine("level: " + match.level);
Console.WriteLine("level_tag: " + match.level_tag);
Console.WriteLine("score: " + match.score);
Console.WriteLine("sequence_ac: " + match.sequence_ac);
Console.WriteLine("sequence_db: " + match.sequence_db);
Console.WriteLine("sequence_id: " + match.sequence_id);
Console.WriteLine("signature_ac: " + match.signature_ac);
Console.WriteLine("signature_id: " + match.signature_id);
Console.WriteLine("start: " + match.start);
Console.WriteLine("stop: " + match.stop);
Console.WriteLine("");
}
}
Console.ReadKey();
}
}
}
这是根节点 'matchset' 模型的 class:
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.ServiceModel;
namespace ConsoleApplication4
{
[Serializable]
[XmlSerializerFormat]
[DataContract(Name = "matchset", Namespace = "urn:expasy:scanprosite")]
[XmlRoot(ElementName = "matchset", Namespace = "urn:expasy:scanprosite")]
public class matchset
{
[DataMember(Name = "match")]
[XmlElement("match")]
public match[] match;
[DataMember(Name = "n_match", IsRequired = true)]
[XmlAttribute("n_match")]
public string n_match;
[DataMember(Name = "n_seq", IsRequired = true)]
[XmlAttribute("n_seq")]
public string n_seq;
}
}
这里是 'match' 模型的代码:
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.ServiceModel;
namespace ConsoleApplication4
{
[Serializable]
[XmlSerializerFormat]
[DataContract(Name = "match", Namespace = "")]
public class match
{
[DataMember(Name = "sequence_ac")]
[XmlElement("sequence_ac")]
public string sequence_ac;
[DataMember(Name = "sequence_id")]
[XmlElement("sequence_id")]
public string sequence_id;
[DataMember(Name = "sequence_db")]
[XmlElement("sequence_db")]
public string sequence_db;
[DataMember(Name = "start")]
[XmlElement("start")]
public string start;
[DataMember(Name = "stop")]
[XmlElement("stop")]
public string stop;
[DataMember(Name = "signature_ac")]
[XmlElement("signature_ac")]
public string signature_ac;
[DataMember(Name = "signature_id")]
[XmlElement("signature_id")]
public string signature_id;
[DataMember(Name = "level_tag")]
[XmlElement("level_tag")]
public string level_tag;
[DataMember(Name = "score")]
[XmlElement("score")]
public string score;
[DataMember(Name = "level")]
[XmlElement("level")]
public string level;
}
}
这是正在反序列化的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<matchset xmlns="urn:expasy:scanprosite" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:expasy:scanprosite http://expasy.org/tools/scanprosite/scanprosite.xsd" n_match="13" n_seq="1">
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>54</start>
<stop>169</stop>
<signature_ac>PS50024</signature_ac>
<signature_id>SEA</signature_id>
<score>32.979</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>183</start>
<stop>222</stop>
<signature_ac>PS50068</signature_ac>
<signature_id>LDLRA_2</signature_id>
<score>10.75</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>197</start>
<stop>221</stop>
<signature_ac>PS01209</signature_ac>
<signature_id>LDLRA_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>225</start>
<stop>334</stop>
<signature_ac>PS01180</signature_ac>
<signature_id>CUB</signature_id>
<score>13.293</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>345</start>
<stop>504</stop>
<signature_ac>PS50060</signature_ac>
<signature_id>MAM_2</signature_id>
<score>42.203</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>391</start>
<stop>431</stop>
<signature_ac>PS00740</signature_ac>
<signature_id>MAM_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>524</start>
<stop>634</stop>
<signature_ac>PS01180</signature_ac>
<signature_id>CUB</signature_id>
<score>17.206</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>642</start>
<stop>678</stop>
<signature_ac>PS50068</signature_ac>
<signature_id>LDLRA_2</signature_id>
<score>13.3</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>655</start>
<stop>677</stop>
<signature_ac>PS01209</signature_ac>
<signature_id>LDLRA_1</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>678</start>
<stop>788</stop>
<signature_ac>PS50287</signature_ac>
<signature_id>SRCR_2</signature_id>
<score>16.02</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>785</start>
<stop>1019</stop>
<signature_ac>PS50240</signature_ac>
<signature_id>TRYPSIN_DOM</signature_id>
<score>39.104</score>
<level>0</level>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>821</start>
<stop>826</stop>
<signature_ac>PS00134</signature_ac>
<signature_id>TRYPSIN_HIS</signature_id>
<level_tag>(0)</level_tag>
</match>
<match>
<sequence_ac>P98073</sequence_ac>
<sequence_id>ENTK_HUMAN</sequence_id>
<sequence_db>sp</sequence_db>
<start>965</start>
<stop>976</stop>
<signature_ac>PS00135</signature_ac>
<signature_id>TRYPSIN_SER</signature_id>
<level_tag>(0)</level_tag>
</match>
</matchset>
XmlSerializationHelper class 由@dbc 在接受的答案中提供:
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication4
{
public static class XmlSerializationHelper
{
public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
{
using (var textWriter = new StringWriter())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // For cosmetic purposes.
settings.IndentChars = " "; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
{
if (omitStandardNamespaces)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
serializer.Serialize(xmlWriter, obj, ns);
}
else
{
serializer.Serialize(xmlWriter, obj);
}
}
return textWriter.ToString();
}
}
public static string GetXml<T>(this T obj, XmlSerializer serializer)
{
return GetXml(obj, serializer, false);
}
public static string GetXml<T>(this T obj, bool omitNamespace)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
return GetXml(obj, serializer, omitNamespace);
}
public static string GetXml<T>(this T obj)
{
return GetXml(obj, false);
}
public static T LoadFromXML<T>(this string xmlString)
{
return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
}
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
{
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = serial.Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
}
}
谢谢。
您的 类 包含数据协定属性和 XmlSerializer
属性的混合。由于属性 [XmlSerializerFormat]
的应用,我假设您正在使用 XmlSerializer
。在这种情况下,您需要:
将
XmlRoot
属性放回matchset
:[Serializable] [XmlSerializerFormat] [DataContract(Name = "matchset", Namespace = "urn:expasy:scanprosite")] [XmlRoot(ElementName = "matchset", Namespace = "urn:expasy:scanprosite")] public class matchset {
将
public match[] match
改为XmlElement
:[DataMember(Name = "match")] [XmlElement("match")] public match[] match { get { return this.matchField; } set { this.matchField = value; } }
这样做之后,我能够读取您 post 中给出的 xml 字符串。
答案基于您的原始 类,而非您修改后的 类。以下是我的测试方式:
public static class TestMatchSet
{
public static void Test()
{
var xml = XmlProvider.GetXml(); // Returns the long XML string from the post.
var matchSet = XmlSerializationHelper.LoadFromXML<matchset>(xml);
Debug.WriteLine(matchSet.GetXml());
}
}
public static class XmlSerializationHelper
{
public static string GetXml<T>(T obj, XmlSerializer serializer, bool omitStandardNamespaces)
{
using (var textWriter = new StringWriter())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // For cosmetic purposes.
settings.IndentChars = " "; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
{
if (omitStandardNamespaces)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
serializer.Serialize(xmlWriter, obj, ns);
}
else
{
serializer.Serialize(xmlWriter, obj);
}
}
return textWriter.ToString();
}
}
public static string GetXml<T>(this T obj, XmlSerializer serializer)
{
return GetXml(obj, serializer, false);
}
public static string GetXml<T>(this T obj, bool omitNamespace)
{
XmlSerializer serializer = new XmlSerializer(obj.GetType());
return GetXml(obj, serializer, omitNamespace);
}
public static string GetXml<T>(this T obj)
{
return GetXml(obj, false);
}
public static T LoadFromXML<T>(this string xmlString)
{
return xmlString.LoadFromXML<T>(new XmlSerializer(typeof(T)));
}
public static T LoadFromXML<T>(this string xmlString, XmlSerializer serial)
{
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = serial.Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
}