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

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
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

流暢な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 に答える