0

我正在尝试使用 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,
                        };

第一个问题(理论上)已解决。到...

第二个问题是我需要提取一些属性(即疏水性、分子量和分子式),但我感到困惑的是属性种类和属性值存储在两个不同的 XElement 中。如何将属性值限制在我关心的字段中?

4

2 回答 2

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

于 2012-07-03T21:30:13.787 回答
1

我已经粘贴了你的代码:输出:

foo
Some info here
1 to 3 hours
90%

正如预期的那样

于 2012-07-03T20:13:37.507 回答