因此,我尝试使用linq将以下xml代码解析为类,并且很难获取内部列表。 xml包含在我正在解析的XDocument中。
<Response>
<ResponseTransaction>
<transaction>
<tranId>3216</tranId>
<tranName>TestTran01</tranName>
<tranResultList>
<tranResult>
<state>Expired</state>
<created>2019-02-23</created>
<docList>
<doc id="1" name="Doc1" />
<doc id="2" name="Doc2" />
<doc id="3" name="Doc3" />
<doc id="4" name="Doc4" />
</docList>
<roleList>
<role role="usrRole" id="1">
<firstName>Jack</firstName>
<lastName>Daniels</lastName>
<email>jd@gmail.com</email>
<docList>
<doc id="1" name="Doc1" status="removed" />
<doc id="2" name="Doc2" status="current" />
<doc id="3" name="Doc3" status="current" />
<doc id="4" name="Doc4" status="current" />
</docList>
</role>
</roleList>
</tranResult>
<tranResult>
<state>undefined</state>
<created>2019-02-24</created>
<docList>
<doc id="1" name="Doc1" />
<doc id="2" name="Doc2" />
<doc id="3" name="Doc3" />
<doc id="4" name="Doc4" />
</docList>
<roleList>
<role role="usrRole" id="1">
<firstName>Jack</firstName>
<lastName>Daniels</lastName>
<email>jd@gmail.com</email>
<docList>
<doc id="1" name="Doc1" status="removed" />
<doc id="2" name="Doc2" status="current" />
<doc id="3" name="Doc3" status="current" />
<doc id="4" name="Doc4" status="current" />
</docList>
</role>
</roleList>
</tranResult>
<tranResult>
<state>Current</state>
<created>2019-02-25</created>
<docList>
<doc id="1" name="Doc1" />
<doc id="2" name="Doc2" />
<doc id="3" name="Doc3" />
<doc id="4" name="Doc4" />
</docList>
<roleList>
<role role="usrRole" id="1">
<firstName>Jack</firstName>
<lastName>Daniels</lastName>
<email>jd@gmail.com</email>
<docList>
<doc id="1" name="Doc1" status="removed" />
<doc id="2" name="Doc2" status="current" />
<doc id="3" name="Doc3" status="current" />
<doc id="4" name="Doc4" status="current" />
</docList>
</role>
</roleList>
</tranResult>
</tranResultList>
</transaction>
</ResponseTransaction>
</Response>
这是我正在使用的课程。
public class Transaction {
public string TranId { get; set; }
public string TranName { get; set; }
public List<TranResult> TranResultList { get; set; }
}
public class TranResult {
public string State { get; set; }
public string DateCreated { get; set; }
public List<Document> DocumentList { get; set; }
public List<Role> RoleList { get; set; }
}
public class Document {
public string Id { get; set; }
public string Name { get; set; }
public string status { get; set; }
}
public class Role {
public string Id { get; set; }
public string RoleName { get; set; }
public User user { get; set; }
}
public class User {
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public List<Document> DocumentList { get; set; }
}
如果此XML文档中没有内部列表,那将很简单,我可以做一个简单的LINQ查询即可。我不确定是否可以遍历内部列表。
感谢您的帮助。
答案 0 :(得分:2)
有三个问题
请参见下面的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Response));
Response response = (Response)serializer.Deserialize(reader);
}
}
[XmlRoot("Response")]
public class Response
{
[XmlElement("ResponseTransaction")]
public ResponseTransaction responseTransaction { get; set; }
}
[XmlRoot("ResponseTransaction")]
public class ResponseTransaction
{
[XmlElement("transaction")]
public Transaction transaction { get; set; }
}
[XmlRoot("transaction")]
public class Transaction
{
[XmlElement("tranId")]
public string TranId { get; set; }
[XmlElement("tranName")]
public string TranName { get; set; }
[XmlArray("tranResultList")]
[XmlArrayItem("tranResult")]
public List<TranResult> TranResultList { get; set; }
}
public class TranResult
{
[XmlElement("state")]
public string State { get; set; }
[XmlElement("created")]
public string DateCreated { get; set; }
[XmlArray("docList")]
[XmlArrayItem("doc")]
public List<Document> DocumentList { get; set; }
[XmlArray("roleList")]
[XmlArrayItem("role")]
public List<Role> RoleList { get; set; }
}
public class Document
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("status")]
public string status { get; set; }
}
public class Role
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("role")]
public string RoleName { get; set; }
[XmlElement("firstName")]
public string FirstName { get; set; }
[XmlElement("lastName")]
public string LastName { get; set; }
[XmlElement("email")]
public string Email { get; set; }
[XmlArray("docList")]
[XmlArrayItem("doc")]
public List<Document> DocumentList { get; set; }
}
}
添加了班级用户
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Response));
Response response = (Response)serializer.Deserialize(reader);
}
}
[XmlRoot("Response")]
public class Response
{
[XmlElement("ResponseTransaction")]
public ResponseTransaction responseTransaction { get; set; }
}
[XmlRoot("ResponseTransaction")]
public class ResponseTransaction
{
[XmlElement("transaction")]
public Transaction transaction { get; set; }
}
[XmlRoot("transaction")]
public class Transaction
{
[XmlElement("tranId")]
public string TranId { get; set; }
[XmlElement("tranName")]
public string TranName { get; set; }
[XmlArray("tranResultList")]
[XmlArrayItem("tranResult")]
public List<TranResult> TranResultList { get; set; }
}
public class TranResult
{
[XmlElement("state")]
public string State { get; set; }
[XmlElement("created")]
public string DateCreated { get; set; }
[XmlArray("docList")]
[XmlArrayItem("doc")]
public List<Document> DocumentList { get; set; }
[XmlArray("roleList")]
[XmlArrayItem("role")]
public List<Role> RoleList { get; set; }
}
public class Document
{
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("status")]
public string status { get; set; }
}
public class Role
{
private User user = new User();
[XmlAttribute("id")]
public string Id { get; set; }
[XmlAttribute("role")]
public string RoleName { get; set; }
[XmlElement("firstName")]
public string FirstName {
get { return user.FirstName; }
set { user.FirstName = value; }
}
[XmlElement("lastName")]
public string LastName
{
get { return user.LastName; }
set { user.LastName = value; }
}
[XmlElement("email")]
public string Email
{
get { return user.Email; }
set { user.Email = value; }
}
[XmlArray("docList")]
[XmlArrayItem("doc")]
public List<Document> DocumentList {
get { return user.DocumentList; }
set { user.DocumentList = value; }
}
}
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public List<Document> DocumentList { get; set; }
}
}
答案 1 :(得分:0)
以下是一些可以使用的功能。使用ClassinstanceFromXML从最里面构建它,它将完成:
public static XElement GetTransaction(XDocument xDoc)
{
return xDoc.Descendants("transaction").FirstOrDefault();
}
public static Transaction TransactionFromXML(XElement transactionXElement)
{
string tranId = transactionXElement.Element("tranId").Value;
string tranName = transactionXElement.Element("tranName").Value;
//transform all <tranResult> Xelements into Class objects
//by passing the xml content of those tags into the TransResultFromXML selector function
List<TranResult> transResults = transactionXElement.Element("tranResultList")?
.Elements("tranResult")?.Select(TransResultFromXML).ToList();
Transaction t = new Transaction()
{
TranId = tranId,
TranName = tranName,
TranResultList = transResults
};
return t;
}
public static TranResult TransResultFromXML(XElement transResultElement)
{
string state = transResultElement.Element("state").Value;
string dateCreated = transResultElement.Element("created").Value;
List<Document> docList;
//transform all <doc> Xelements in <docList> into Class objects
//by passing the xml content of those tags into the DocumentFromXML selector function
docList = transResultElement.Element("docList")?
.Elements("doc")?.Select(DocumentFromXML).ToList();
List<Role> roleList;
//transform all <role> Xelements in <roleList> into Class objects
//by passing the xml content of those tags into the RoleFromXML selector function
roleList = transResultElement.Element("roleList")?
.Elements("role")?.Select(RoleFromXML).ToList();
return new TranResult()
{
State = state,
DateCreated = dateCreated,
DocumentList = docList,
RoleList = roleList
};
}
public static Role RoleFromXML(XElement roleElement)
{
string id = roleElement.Attribute("id").Value;
string roleName = roleElement.Attribute("role").Value;
//A similar apttern has been used above - do same here
List<Document> userDocList = roleElement.Element("docList")?
.Elements("doc")?.Select(DocumentFromXML).ToList();
User myUser = new User()
{
FirstName = roleElement.Element("firstName")?.Value,
LastName = roleElement.Element("lastName")?.Value,
Email = roleElement.Element("email")?.Value,
DocumentList = userDocList
};
return new Role()
{
Id = id,
RoleName = roleName,
user = myUser
};
}
public static Document DocumentFromXML(XElement docElement)
{
return new Document()
{
Id = docElement.Attribute("id").Value,
Name = docElement.Attribute("name").Value,
status = docElement.Attribute("status")?.Value
};
}
static void Main(string[] args)
{
XDocument x = XDocument.Load(@"Path\To\transactions.xml");
Transaction myTransaction = TransactionFromXML(GetTransaction(x));
Console.WriteLine(myTransaction.TranResultList.ElementAt(1).RoleList.ElementAt(0).user.Email);
Console.ReadLine();
}
答案 2 :(得分:0)
public static class MyMethods
{
public static void XMLWrite<T>(this T obj, string PathXML) where T : class, new()
{
if (Directory.Exists(Path.GetDirectoryName(PathXML)))
{
using (FileStream stream = new FileStream(PathXML, FileMode.Create))
using (XmlTextWriter writer = new XmlTextWriter(stream, Encoding.Unicode))
{
XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
xmlSerializer.Serialize(writer, obj);
}
}
}
public static T XMLRead<T>(this string PathXML) where T : class, new()
{
if (File.Exists(PathXML))
{
XmlSerializer xmlOkuyucu = new XmlSerializer(typeof(T));
using (Stream okuyucu = new FileStream((PathXML), FileMode.Open))
{
return (T)xmlOkuyucu.Deserialize(okuyucu);
}
}
return default(T);
}
}
使用通用方法,您可以写入或读取包含列表的对象。
示例:
object1 = MyMethods.XMLRead<YourClass>(string.Format("{0}\\{1}", locationXML, "file1.xml"));
object2 = MyMethods.XMLRead<List<YourClass2>>(string.Format("{0}\\{1}", locationXML, "file2.xml"));
object3.XMLWrite(Path.GetDirectoryName(Application.ExecutablePath) + "\\file3.xml");