如何使用linq解析这个xml

时间:2013-09-24 23:33:04

标签: xml linq

我有以下需要使用linq解析并获取值的xml

<?xml version="1.0" encoding="UTF-8"?>
<questestinterop xmlns="http://www.imsglobal....." xmlns:xsi="http://www.w3.org...." xsi:schemaLocation="http://www.imsglobal.org/.....xsd">
  <assessment ident="gh" title="Sample">
    <qtimetadata>
      <qtimetadatafield>
        <fieldlabel>cc_maxattempts</fieldlabel>
        <fieldentry>1</fieldentry>
      </qtimetadatafield>
    </qtimetadata>
    <section ident="rs">
      <item ident="ghg" title="Question">
        <itemmetadata>
          <qtimetadata>
            <qtimetadatafield>
              <fieldlabel>question_type</fieldlabel>
              <fieldentry>yyy</fieldentry>
            </qtimetadatafield>
            <qtimetadatafield>
               <fieldlabel>points_possible</fieldlabel>
               <fieldentry>1</fieldentry>
            </qtimetadatafield>
            <qtimetadatafield>
                <itemmetadata>
                <presentation>
                  .........
                </presentation>
      </item>
      <item ident="hj" title="Question">
        ....
      </item>
    </section>
  </assessment>
</questestinterop>

我需要获得yyy的值where fieldlabel = questiontype。我如何使用linq做到这一点?尝试以下方法:

XDocument document = XDocument.Load(assessmentXmlName);
XNamespace ns = "http://www.imsglobal.org/xsd/ims_qtiasiv1p2";


var results = from main in document.Root
             .Elements(ns + "assessment")
             .Elements(ns + "section")
             .Elements(ns + "item")
             .Elements(ns + "itemmetadata")
             .Elements(ns + "qtimetadata")
             .Descendants("qtimetadatafield")
              select new
                  {
                      itemtype = (string)main.Element(ns + "fieldentry").Value,
                  };

让我知道

1 个答案:

答案 0 :(得分:0)

要将结果范围缩小到fieldentry其兄弟fieldlabel为“question_type”的字段,您可以添加where子句:

var results = from main in document.Root
                            .Descendants(ns + "qtimetadatafield")
              where (string)main.Element(ns + "fieldlabel") == "question_type"
              select new
              {
                  itemtype = (string)main.Element(ns + "fieldentry")
              };

有几点需要注意:

  • 我删除了所有Element次来电。除非你有理由像你一样具体,比如嵌套在不同元素中的重复元素名称,只需抓住你感兴趣的名称Descendants即可。
  • 将元素结果转换为string时,您不应该调用.Value,因为当该元素不存在时会抛出NullReferenceException。我删除了.Value次调用并保留了字符串强制转换。