我有一个类似于下面的xml,其中root为rail
<rail>
<timetable>
<trainParts>
<trainPart id="tp_1" name="1" timetablePeriodRef="ttp_2012_13" categoryRef="cat_Commuter" processStatus="planned" trainNumber="1">
<operatingPeriodRef ref="Daily" />
<ocpsTT>
<ocpTT ocpType="begin" ocpRef="ocp_SWH">
<sectionTT trackInfo="SWH-DM" />
</ocpTT>
<ocpTT ocpType="stop" ocpRef="ocp_SE">
<times arrival="16:16:00" departure="16:18:00" scope="scheduled" />
<sectionTT trackInfo="SE-DM" />
</ocpTT>
.
.
.
so on
</ocpsTT>
</trainPart>
</trainParts>
</timetable>
</rail>
现在这样有很多列车编号,我必须一次解析其详细信息。 我可以使用linq一次解析一个孩子及其属性,但我想解析所有的孩子及其元素。 比如说trainNumer =“1”我需要得到
categoryRef
processStatus
operatingPeriodRef
ocpType
ocpRef
trackInfo
arrival
departure
注意:在某些情况下,包含出发到达的标签不在那里
我确实尝试编写如下代码:
public void trainDetails(string trainNumber)
{
var xdoc = XDocument.Load("Rail.xml");
XNamespace ad = "http://www.rail.org/schemas/2009";
var train = (from t in xdoc.Root.Elements(ad + "timetable")
let d = t.Element(ad + "trainParts").Element("trainPart")
where (string)t.Attribute("number") == trainNumber
select new
{
operatingPeriod=(from s1 in d.Elements(ad+"operatingPeriodRef")
operatingref=(string)s1.Attribute("ref")
}).ToList()
}
select new
{
trainOcpsTT= (from s2 in d.Elements(ad + "ocpsTT").Elements(ad+"ocpTT")
select new
{
ocpType=(string)s2.Attribute("ocpType"),
ocpRef=(string)s2.Attribute("ocpRef")
}).ToList()
}).FirstOrDefault();
}
}
我无法正确构建查询.. 是否可以在一个xml linq查询中获取所有这些?如何? 如果不是那么在这种情况下哪种方法是正确的..
答案 0 :(得分:1)
以下是我的建议:
public class TrainInfo
{
public string categoryRef { get; set; }
public int trainNumber { get; set; }
public string processStatus { get; set; }
public string operatingPeriodRef { get; set; }
public List<ocpsTTs> ocpsTT { get; set; }
}
public struct ocpsTTs
{
public string ocpType;
public string ocpRef;
public string arrival;
public string departure;
public string scope;
public string trackInfo;
}
class Program
{
static void Main(string[] args)
{
TrainInfo ti = ProcessXml(@"XMLFile1.xml", 1);
}
static TrainInfo ProcessXml(string xmlfile, int trainnumber)
{
TrainInfo retVal;
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlfile);
XNamespace xns = "http://www.rail.org/schemas/2009";
XDocument xdoc = System.Xml.Linq.XDocument.Parse(xmlDoc.InnerXml);
retVal =
(from c
in xdoc.Root.Elements(xns + "timetable").Elements(xns + "trainParts").Elements(xns + "trainPart")
where c.Attribute("trainNumber").Value.Equals(trainnumber.ToString())
select new TrainInfo
{
categoryRef = c.Attribute("categoryRef").Value,
trainNumber = Int32.Parse(c.Attribute("trainNumber").Value),
processStatus = c.Attribute("processStatus").Value,
operatingPeriodRef = c.Element(xns + "operatingPeriodRef").Attribute("ref").Value,
ocpsTT = (from tt in c.Elements(xns + "ocpsTT").Descendants(xns + "ocpTT")
let timeinfo = tt.Elements(xns + "times").Any()
select new ocpsTTs
{
ocpType = tt.Attribute("ocpType").Value,
ocpRef = tt.Attribute("ocpRef").Value,
arrival = timeinfo ? tt.Element(xns + "times").Attribute("arrival").Value : string.Empty,
departure = timeinfo ? tt.Element(xns + "times").Attribute("departure").Value : string.Empty,
scope = timeinfo ? tt.Element(xns + "times").Attribute("scope").Value : string.Empty,
trackInfo = tt.Element(xns + "sectionTT").Attribute("trackInfo").Value,
}).ToList()
}).FirstOrDefault();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
retVal = null;
}
return retVal;
}
}