8

カスタム構成ファイルが1つあります。

<Students>
 <student>
   <Detail Name="abc" Class="1st Year">
       <add key="Main" value="web"/>
       <add key="Optional" value="database"/>
   </Detail>
 </student>
</Students>

IConfigurationHandlerインターフェイスの実装を通じてこのファイルを読み取りました。Detail要素のchildNode属性を読み取ったとき。以下の結果をIDEのイミディエイトウィンドウに返します。

elem.Attributes.ToObjectArray()

{object[2]}
    [0]: {Attribute, Name="key", Value="Main"}
    [1]: {Attribute, Name="value", Value="web"}

コンソールで書き込もうとすると

 Console.WriteLine("Value '{0}'",elem.Attributes.ToObjectArray());

それは私を返します

Value : 'System.Configuration.ConfigXmlAttribute'

elem.Attributes.Item(1)メソッドは名前と値の詳細を教えてくれますが、ここでは現在わからない属性のインデックス値を渡す必要があります。

次のように、 LINQクエリを使用して属性の名前と値を取得し、各childNode属性のコンソールに個別に表示したいと思います。

Value : Name="Key" and Value="Main"
        Name="value", Value="web"

どうすればそれを達成できますか?

4

4 に答える 4

3

Linq Selectstring.Joinを使用して、必要な出力を取得できます。

string.Join(Environment.NewLine, 
    elem.Attributes.ToObjectArray()
        .Select(a => "Name=" + a.Name + ", Value=" + a.Value)
)
于 2012-05-24T08:06:49.370 に答える
3

このXmlライブラリを使用する場合は、次のコードを使用してすべての学生とその詳細を取得できます。

XElement root = XElement.Load(file); // or .Parse(string)
var students = root.Elements("student").Select(s => new
{
    Name = s.Get("Detail/Name", string.Empty),
    Class = s.Get("Detail/Class", string.Empty),
    Items = s.GetElements("Detail/add").Select(add => new
    {
        Key = add.Get("key", string.Empty),
        Value = add.Get("value", string.Empty)
    }).ToArray()
}).ToArray();

次に、それらを反復処理するには、次を使用します。

foreach(var student in students)
{
    Console.WriteLine(string.Format("{0}: {1}", student.Name, student.Class));
    foreach(var item in student.Items)
        Console.WriteLine(string.Format("  Key: {0}, Value: {1}", item.Key, item.Value));
}
于 2012-06-14T20:38:29.377 に答える
2

これにより、質問で述べたように、Detail要素の子のすべての属性が取得されます。

XDocument x = XDocument.Parse("<Students> <student> <Detail Name=\"abc\" Class=\"1st Year\"> <add key=\"Main\" value=\"web\"/> <add key=\"Optional\" value=\"database\"/> </Detail> </student> </Students>");

var attributes = x.Descendants("Detail")
                  .Elements()
                  .Attributes()
                  .Select(d => new { Name = d.Name, Value = d.Value }).ToArray();

foreach (var attribute in attributes)
{
     Console.WriteLine(string.Format("Name={0}, Value={1}", attribute.Name, attribute.Value));
}
于 2012-06-17T02:06:31.370 に答える
0

あなたが書いたように属性を持っている場合object[]、それはによって嘲笑される可能性があります

var Attributes = new object[]{
    new {Name="key", Value="Main"},
    new {Name="value", Value="web"}
};

問題は、名前を簡単に抽出できない匿名型があることです。

このコードを見てください(LinqPadエディターウィンドウのmain()メソッドに貼り付けて実行できます)。

var linq=from a in Attributes
let s = string.Join(",",a).TrimStart('{').TrimEnd('}').Split(',')
select new 
{
    Value = s[0].Split('=')[1].Trim(),
    Name = s[1].Split('=')[1].Trim()
};
//linq.Dump();

コンパイラが変数Attributesを非表示にするため、 object []配列内の変数AttributesのNameプロパティとValueプロパティにアクセスできないため、 Join( "、"、a)メソッドを使用してこの制限を回避するのがコツです。

後で行う必要があるのは、結果の文字列をトリミングして分割し、最後にValueプロパティとNameプロパティを使用して新しいオブジェクトを作成することです。linq.Dump();のコメントを外すと、試してみることができます。LinqPadの行-必要なものを返し、さらにLinqステートメントでクエリを実行できます。

于 2012-06-19T12:22:20.263 に答える