LINQ to XMLで動的LINQ式を使用しようとしていますが 、動的パラメーターに問題があります。
以下は、Dynamic LINQ Wikiからのクエリの例です。
var query = db.Customers
.Where("City == @0 and Orders.Count >= @1", "London", 10)
.OrderBy("CompanyName")
.Select("new(CompanyName as Name, Phone)");
たとえば、私の場合、次の構造をクエリしようとしています。
<DataCenter>
<Server IP="1.2.3.4">
<OS>Windows</OS>
</Server>
<Server IP="5.6.7.8">
<OS>Linux</OS>
</Server>
</DataCenter>
私はそれを次のように読んで解析しようとしています:
XElement XmlSource = XElement.Load(filePath)
var query = XmlSource.Elements().AsQueryable().Select("???????");
文字列パラメータとして何を入れますか?たとえば、すべてのサーバーのIPとOSを取得しようとした場合。 XElementのElement( )
またはAttribute( )
メソッドを使用しようとすると、「 XElementにはそのようなプロパティまたはメソッドがない 」というエラーが発生します。
firstAtteibute
とfirstNode
は利用できるようですが。そして、このようなものはうまくいきます:
var query = XmlSource.Elements()
.AsQueryable()
.Select("new (FirstAttribute.Value as IP, FirstNode.toString() as OS)");
System.Linq.Dynamic.Core
を使用していると仮定すると、 XName
とXElement
をアクセス可能な型に追加して、機能するようにすることができます 。
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider {
public override HashSet<Type> GetCustomTypes() => new[] { typeof(XName), typeof(XElement) }.ToHashSet();
}
動的LINQはメソッド検索に暗黙の変換を使用せず、明示的な変換を理解しないため、通常は暗黙の変換によって行われるstring
からXName
への変換を処理する2つの異なる方法を示しました。
ParsingConfig.Default.CustomTypeProvider = new MyCustomTypeProvider();
var OSName = (XName)"OS";
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, Element(@0).Value as OS)", OSName);
要素OS
が欠落している可能性がある場合は、 null
テストする必要がありnull
。残念ながら、 np
述部を機能させることができませんでした。
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, (Element(@0) != null ? Element(@0).Value : null) as OS)", OSName);
string xml =
"<DataCenter><Server IP=\"1.2.3.4\"><OS>Windows</OS></Server><Server IP=\"5.6.7.8\"><OS>Linux</OS></Server></DataCenter>";
XDocument doc = XDocument.Parse(xml);
var servers = doc.Elements("DataCenter").Elements("Server");
var results = from s in doc.Elements("DataCenter").Elements("Server") where (string)s.Attribute("IP") == "1.2.3.4" select s;
編集:
これはXMLであり、要素/属性の値が必要なため、 Value
プロパティを取得するだけでは不十分です。その場合、アクセス可能な型を処理する理由はありません。
XDocument doc2 = XDocument.Parse(xml);
var results = from s in doc2.Descendants("Server") select new { OsName = s.Element("OS").Value, IpAddress = s.Attribute("IP").Value };