1

我有一个如下所示的 xml。

我需要编写一个方法,该方法接受字符串输入(“IsAuthorFilterNeeded”或“IsTitleFilterNeeded”)并返回该节点下的书籍代码值。

假设如果参数是“IsAuthorFilterNeeded”,它应该返回 5,6,7,8

我尝试编写一个 Linq2XML 查询来检索它,但我对代码不满意,因为它不可读并且有许多硬编码的字符串。这是我的 linq2xml 查询。

public IList<string> GetBookCodes(string filterOption)
{
    IList<string> requiredValues = null;

    foreach (var node in _xml.Descendants("BookOptions"))
    {
        if (node.Parent.Attribute("Name").Value == "ScienceBooks")
        {
            var requiredNode = node.Elements("Property").Attributes("Value").First(x => x.Parent.FirstAttribute.Value == filterOption);
            requiredValues = requiredNode.Parent.Descendants("BookCode").Attributes("Value").ToArray().Select(x => x.Value).ToList();

            break;
        }
    }
    return requiredValues;
}

有没有其他方法可以用更简单的代码来实现这个结果。

<LibraryRack Id="3" Name="ScienceBooks">
      <Books>
        <Book Id ="1" Name="Book1"></Book>
        <Book Id ="2" Name="Book2"></Book >
        <Book Id ="3" Name="Book3"></Book>
      </Books>
      <BookOptions>
        <Property Name="IsAuthorFilterNeeded" Value ="1">
          <BookCode Value="5" />
          <BookCode Value="6" />
          <BookCode Value="7" />
          <BookCode Value="8" />
        </Property>
        <Property Name="IsTitleFilterNeeded" Value ="0">
          <BookCode Value="2"/>
          <BookCode Value="3"/>
          <BookCode Value="4"/>
          <BookCode Value="7"/>
          <BookCode Value="129"/>
        </Property>
       </BookOptions> 

    </LibraryRack>
4

3 回答 3

1
using(FileStream fs = new FileStream("somedata.xml",FileMode.Open))
{
  var result = XDocument.Load(fs).Descendants("BookOptions").
                                  Descendants("Property").
                                  Where(c => { return c.Attribute("Name").Value.Trim() == "IsAuthorFilterNeeded"; }).
                                  Descendants().Select(xe => xe.Attribute("Value"));

  result.ToList().ForEach((val) => Console.WriteLine(val));
}
于 2012-10-30T06:29:53.803 回答
1

这一点 LINQ 应该可以解决问题(一旦你的 XML 被修复):

public IList<string> GetBookCodes(string filterOption)
{
    return (from property in _xml.Descendants("Property")
            where (string)property.Attribute("Name") == filterOption
            from value in property.Descendants("BookCode").Attributes("Value")                
            select (string)value).ToList();
}
于 2012-10-30T06:20:16.577 回答
1

我认为 fluent api 在这里看起来更具可读性

var propertyFilter = "IsAuthorFilterNeeded";
var query = xdoc.Descendants("LibraryRack")
                .Where(lr => (string)lr.Attribute("Name") == "ScienceBooks")
                .Descendants("Property")
                .Where(p => (string)p.Attribute("Name") == propertyFilter)
                .Descendants()
                .Select(bc => (int)bc.Attribute("Value"));
于 2012-10-30T07:14:42.403 回答