1

请查看下面的代码并建议需要做什么才能在输出中获得额外的最后一行,如预期输出中所示

class test {

   static void Main(string[] args)
    {

        XDocument doc = XDocument.Load("E:\\BI_analytics\\Data\\so.xml");
        var query = from test in doc.Descendants("tester")
                    from testreq in test.Descendants("testRequest")
                    from testresp in test.Descendants("testResponse")
                    let id = testreq.Element("id") == null ? string.Empty : testreq.Element("id").Value

                  //  select id;
                    from itm in testresp.Descendants("item")
                    select new
                    {
                        ID = (string)id,
                        Name = (string)itm.Attribute("itemname"),
                        Code = (string)itm.Attribute("itemocde"),
                    };


        foreach (var result in query)
        {
            Console.WriteLine(result);
        }
    }
}

电流输出

{ ID = 2,名称 = 测试项目 1,代码 = 111 }
{ ID = 2,名称 = 测试项目 2,代码 = 222 }
{ ID = 3,名称 = 测试项 3,代码 = 333 }
{ ID = 3,名称 = 测试项 4,代码 = 444 }

预期产出

{ ID = 2,名称 = 测试项目 1,代码 = 111 }
{ ID = 2,名称 = 测试项目 2,代码 = 222 }
{ ID = 3,名称 = 测试项 3,代码 = 333 }
{ ID = 3,名称 = 测试项 4,代码 = 444 }
{ ID = 4,名称 = ,代码 = }
<?xml version="1.0" encoding="utf-8"?>
<root>
  <tester>
    <testRequest>
      <id>2</id>
    </testRequest>
    <testResponse>
      <items>
        <item itemname="test item1" itemocde="111"/>
        <item itemname="test item2" itemocde="222"/>
      </items>
    </testResponse>
  </tester>
  <tester>
    <testRequest>
      <id>3</id>
    </testRequest>
    <testResponse>
      <items>
        <item itemname="test item3" itemocde="333"/>
        <item itemname="test item4" itemocde="444"/>
      </items>
    </testResponse>
  </tester>
  <tester>
    <testRequest>
      <id>4</id>
    </testRequest>
    <testResponse>
      <items />
    </testResponse>
  </tester>
</root>
4

2 回答 2

3

我使用一个类来帮助我返回值,即使它是 null 看起来像这样:

public static class LinqToXMLUtility
{
    /// <summary>
    /// Used to Get check the XElement Value and return 
    /// empty string if it is null (used for optional or missing xml items)
    /// </summary>
    /// <param name="pElement"></param>
    /// <param name="pstrElementName"></param>
    /// <returns></returns>
    public static string GetXElementValue(XElement pElement, string pstrElementName)
    {
        string strRet = string.Empty;
        try
        {
            XElement lElement = pElement.Element(pstrElementName);
            if (lElement != null)
            {
                strRet = lElement.Value;
            }
        }
        catch { }
        return strRet;
    }
}

并像这样使用它。

class test
{
    static void Main(string[] args)
    {
        XDocument doc = XDocument.Load("E:\\BI_analytics\\Data\\so.xml");
        var query = from test in doc.Descendants("tester")
                    from testreq in test.Descendants("testRequest")
                    from testresp in test.Descendants("testResponse")
                    let id = testreq.Element("id") == null ? string.Empty : 
                             testreq.Element("id").Value

                    //  select id;
                    from itm in testresp.Descendants("item")
                    select new
                    {
                        ID = LinqToXMLUtility.GetXElementValue(itm, "id"),
                        Name = LinqToXMLUtility.GetXElementValue(itm, "itemname"),
                        Code =  LinqToXMLUtility.GetXElementValue(itm, "itemocde"),
                    };


        foreach (var result in query)
        {
            Console.WriteLine(result);
        }
    }
}
于 2012-05-31T16:25:10.480 回答
2

这就是问题:

from itm in testresp.Descendants("item")

你没有任何元素item,所以你可能想要:

from itm in testresp.Descendants("item").DefaultIfEmpty()

...此时您需要:

select new
{
    ID = (string)id,
    Name = itm == null ? "" : (string)itm.Attribute("itemname"),
    Code = itm == null ? "" : (string)itm.Attribute("itemocde"),
};
于 2012-05-31T16:25:09.880 回答