c#linqからXMLクエリヘルプ
-
29-09-2019 - |
質問
次のコンテンツを持つdata.xmlという名前のXMLファイルを想定しましょう。
<root>
<record>
<id>1</id>
<name>test 1</name>
<resume>this is the resume</resume>
<specs>these are the specs</specs>
</record>
<record>
<id>2</id>
<name>test 2</name>
<resume>this is the resume 2</resume>
</record>
<record>
<id>3</id>
<name>test 3</name>
<specs>these are the specs 3</specs>
</record>
</root>
これらのフィールド(ID、名前、履歴書、または仕様)に特定の値が含まれているすべてのレコードを検索する必要があります。このコードを作成しました
XDocument DOC = XDocument.Load("data.xml");
IEnumerable<ProductRecord> results = from obj in DOC.Descendants("record")
where
obj.Element("id").Value.Contains(valueToSearch) ||
obj.Element("name").Value.Contains(valueToSearch) ||
obj.Element("resume").Value.Contains(valueToSearch) ||
obj.Element("specs").Value.Contains(valueToSearch)
select new ProductRecord {
ID = obj.Element("id").Value,
Name = obj.Element("name").Value,
Resume = obj.Element("resume").Value,
Specs = obj.Element("specs").Value
};
すべてのレコードにすべてのフィールドがあるわけではないため、このコードはnullReferenceのエラーをスローします。適用する条件を定義する前に、現在のレコードに特定の要素があるかどうかをテストするにはどうすればよいですか?元。 Record [@id = 3]には履歴書がありません。
前もって感謝します
解決
Bellowのような拡張メソッドを書くことができます:
public static class XMLExtension
{
public static string GetValue(this XElement input)
{
if (input != null)
return input.Value;
return null;
}
public static bool XMLContains(this string input, string value)
{
if (string.IsNullOrEmpty(input))
return false;
return input.Contains(value);
}
}
以下のように使用してください。
IEnumerable<ProductRecord> results = from obj in DOC.Descendants("record")
where
obj.Element("id").GetValue().XMLContains(valueToSearch) || ...
他のヒント
あなたはそれぞれに存在しないいくつかのノードの値にアクセスしようとしているので、あなたはnullReferenceExceptionを取得しています record
お気に入り specs
. 。あなたはかどうかを確認する必要があります obj.Element("specs") != null
電話する前に .Value
その上。
代替手段として、xpathを使用できます。
var doc = XDocument.Load("test.xml");
var records = doc.XPathSelectElements("//record[contains(id, '2') or contains(name, 'test') or contains(resume, 'res') or contains(specs, 'spe')]");
最初に、名前空間を使用していないためにクラッシュしていないことに驚いています。たぶんC#4.0はこれをバイパスしましたか?
とにかく試してみてください
obj.Descendants("id").Any() ? root.Element("id").Value : null
あれは:
select new ProductRecord {
ID = obj.Descendants("id").Any() ? root.Element("id").Value : null,
Name = obj.Descendants("name").Any() ? root.Element("name").Value : null,
Resume = obj.Descendants("resume").Any() ? root.Element("resume").Value : null
Specs = obj.Descendants("specs").Any() ? root.Element("specs").Value : null
};
所属していません StackOverflow