我正在尝试使用LINQ解析出复杂的XML文件。这些文件包含数千条记录,每条记录包含数百个字段。我需要解析有关每种药物的某些信息部分并将其存储在数据库中。
修改 我很抱歉,但最初发布的XML实际上并不准确。我没有意识到这些属性会改变这个过程。我已经更新了问题,以准确描述XML文件的真实性质。
以下是XML的示例:
<<drugs xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://drugbank.ca" xs:schemaLocation="http://www.drugbank.ca/docs/drugbank.xsd" schemaVersion="1.4">
<drug>
<name>foo</name>
<indication>Some info here</indication>
<half-life>1 to 3 hours</half-life>
<protein-binding>90%</protein-binding>
// hundreds of other elements
<properties>
<property>
<kind>logP/hydrophobicity</kind>
<value>-0.777</value>
</property>
<property>
<kind>Molecular Weight</kind>
<value>6963.4250</value>
</property>
<property>
<kind>Molecular Formula</kind>
<value>C287H440N80O110S6</value>
</property>
//dozens of other properties
</properties>
</drug>
// thousands of more drugs
</drugs>
我对实际查询非常模糊,因为这是我第一次使用LINQ。我熟悉SQL,所以复杂查询的概念对我来说并不困难,但我找不到任何可以帮助解决这个问题的文档。我到目前为止的查询如下:
XDocument xdoc = XDocument.Load(@"drugbank.xml");
var d = from drugs in xdoc.Descendants("drug")
select new
{
name = drugs.Element("name").Value,
indication = drugs.Element("indication").Value,
halflife = drugs.Element("half-life").Value,
proteinBinding = drugs.Element("protein-binding").Value,
};
第一个问题是(理论上)解决了。在... ...
第二个问题是我需要提取一些属性(即疏水性,分子量和分子式),但我感到困惑的是,属性种类和属性值存储在两个不同的XElements。如何才能将属性值限制在我关注的字段中?
答案 0 :(得分:1)
我已粘贴您的代码: 输出:
foo
Some info here
1 to 3 hours
90%
正如预期的那样
答案 1 :(得分:1)
您可以执行子查询以将属性获取到外部通用对象的另一个属性中。如果你想要它们嵌套:
XNamespace defaultNS = "http://drugbank.ca";
var d = from drugs in xdoc.Descendants(defaultNS + "drug")
select new
{
name = drugs.Element(defaultNS + "name").Value,
indication = drugs.Element(defaultNS + "indication").Value,
halflife = drugs.Element(defaultNS + "half-life").Value,
proteinBinding = drugs.Element(defaultNS + "protein-binding").Value,
Properties = (from property in drugs.Element(defaultNS + "properties").Elements(defaultNS + "property")
let kind = property.Element(defaultNS + "kind").Value
where kind == "logP/hydrophobicity" || kind == "Molecular Weight" || kind == "Molecular Formula"
select new { Kind = kind, Value = property.Element(defaultNS + "value").Value })
};
或扁平化:
XNamespace defaultNS = "http://drugbank.ca";
var d = from drugs in xdoc.Descendants(defaultNS + "drug")
let properties = drugs.Element(defaultNS + "properties").Elements(defaultNS + "property")
select new
{
name = drugs.Element(defaultNS + "name").Value,
indication = drugs.Element(defaultNS + "indication").Value,
halflife = drugs.Element(defaultNS + "half-life").Value,
proteinBinding = drugs.Element(defaultNS + "protein-binding").Value,
hydrophobicity = (from property in properties
let kind = property.Element(defaultNS + "kind").Value
where kind == "logP/hydrophobicity"
select property.Element(defaultNS + "value").Value).FirstOrdefaultNS(),
molecularWeight = (from property in properties
let kind = property.Element(defaultNS + "kind").Value
where kind == "Molecular Weight" || kind == "Molecular Formula"
select property.Element(defaultNS + "value").Value).FirstOrdefaultNS(),
molecularFormula = (from property in properties
let kind = property.Element(defaultNS + "kind").Value
where kind == "Molecular Formula"
select property.Element(defaultNS + "value").Value).FirstOrdefaultNS()
};
另外,一个非常有用的参考资料可以帮助您了解Linq 101 LINQ Samples。