我有以下XML文件。我试图读取dept元素的startDate节点,但不想读取任何其他子元素的“startDate”节点,如“DeptRoles”。
<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"></endDate>
<DeptRoles>
<DeptRole name="Other dept" status="active">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"/>
<isPrimary/>
</DeptRole>
</DeptRoles>
</dept>
这是我的c#代码。这段代码也得到了我不想要的DeptRole startDate元素。
public static List<organisation> Getorgdata(string data)
{
List<organisation> listorgdata = new List<organisation>();
XmlReader xmlReader = XmlReader.Create(new StringReader(data));
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
organisation record = new organisation();
if (xmlReader.HasAttributes && xmlReader.Name == "dept")
{
record.orgOperationalStatus = xmlReader.GetAttribute("operationalStatus");
record.orgLegalStatus = xmlReader.GetAttribute("legalStatus");
}
else if (xmlReader.Name == "name")
{
record.orgName = xmlReader.ReadElementString("name");
}
else if (xmlReader.Name == "startDate" || xmlReader.Name == "endDate")
{
if (xmlReader.GetAttribute("type") == "legal")
{
record.orgLegalStartDate = xmlReader.ReadElementString("startDate");
record.orgLegalEndDate = xmlReader.ReadElementString("endDate");
}
else if (xmlReader.GetAttribute("type") == "operational")
{
record.orgOperationalStartDate = xmlReader.ReadElementString("startDate");
record.orgOperationalEndDate = xmlReader.ReadElementString("endDate");
listorgdata.Add(record);
}
}
}
}
return listorgdata;
}
答案 0 :(得分:1)
我会使用LINQ to XML(正如其他人所建议的那样)。下面是与您发布的代码有些匹配的示例代码 - 代码说明如下。
public static List<organisation> Getorgdata(string data)
{
List<organisation> listorgdata = new List<organisation>();
XDocument xDoc = XDocument.Parse(data);
listorgdata = xDoc.Root.Elements("dept")
.Select(x => new organisation()
{
orgOperationalStatus = (string)x.Attribute("operationalStatus"),
orgLegalStartDate = (string)x.Elements("startDate")
.Where(x1 => (string)x1.Attribute("type") == "legal")
.First(),
orgOperationalStartDate = (string)x.Elements("startDate")
.Where(x1 => (string)x1.Attribute("type") == "operational")
.First()
}).ToList();
return listorgdata;
}
上面代码的第一件事就是使用XDocument.Parse
方法将XML加载到XDocument中。
然后,查询解析XML文档并返回已填充的organization
个对象的列表。它就是这样的。
<dept>
元素(以及子元素)。<dept>
元素,创建organisation
的新实例,并指定&#34; operationalStatus&#34;的值。属性为operationalStatus
的{{1}}属性。 organisation
强制转换将优雅地处理指定属性不存在的情况。(string)
元素的<startDate>
个子元素进行查询,获取第一个具有属性&#34;类型&#34;等于&#34; legal&#34;。<dept>
扩展程序将IEnumerabale<T>
结果转换为列表。这可能不是最有效的,它并不涵盖您原始代码中的所有属性,但它至少应该让您朝着正确的方向前进。例如,如果你想获得&#34; primaryRole&#34;属性,您只需在.ToList()
块中添加以下行:
new organisation()
如果您需要来自orgPrimaryRole = (string)x.Attribute("primaryRole"),
的数据,那么您可以获得该数据,但它需要更多参与。
如果您更喜欢查询语法而不是方法语法,它将如下所示:
<DeptRoles>
答案 1 :(得分:0)
如果我添加 CATALOG
<CATALOG>
<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"></endDate>
<DeptRoles>
<DeptRole name="Other dept" status="active">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"/>
<isPrimary/>
</DeptRole>
</DeptRoles>
</dept>
</CATALOG>
使用System.Xml.Linq;你可以获得你的清单:
XElement myXML = XElement.Load(@"C:\Users\User\Desktop\myXML.xml");
var deptDescendantsList = (from ep in myXML.Descendants("dept")
select ep.Elements("startDate")).ToList();
答案 2 :(得分:0)
我不确定如何创建完全符合您需求的查询。 尝试将此查询附加到您的需求。 http://msdn.microsoft.com/en-us/library/bb387061.aspx包含有关linq2xml查询的一些信息
XmlReader xmlReader = XmlReader.Create(new StringReader(data));
XDocument d = XDocument.Load(xmlReader);
var startDates = from item in d.Root.Descendants()
where item.Name == "startDate" && item.Parent.Name == "dept" && item.Parent.Attribute("deptid").Value == "anynumber"
select item;
// iterate over the startDates and do your magic
答案 3 :(得分:0)
试试这个:
var readSpecific =来自xd.Descendants中的一个(&#34;部门&#34;)
select new
{
LegalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "legal").Value,
LegalEndDate = a.Element("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "legal").Value,
OperationalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "operational").Value,
OperationEndDate = a.Elements("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "operational").Value
};