0

次のlinqクエリを使用してXMLファイルを操作しています..

XElement rootElement = XElement.Load(@"test.xml"); 
int StyCode; 
var lv1s = from lv1 in rootElement.Descendants("Class") 
where lv1.Attribute("Code").Value.Equals("002") 
select new 
{ 
Children = from ltd in lv1.Descendants("Subject") 
where ltd.Attribute("Course").Value.Equals("Math") 
select new 
{ 

****//In This below section need result on condition based... ****
if(StyCode=0)  
{
Children1 = ltd.Attribute("AllTeachers").Value.Equals("Y") ? true : false
}
else
{
Children2 = ltd.Attribute("SpeciaGuest").Value.Equals("Y") ? true : ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null ? true : false 
}
} 
}; 

以下は私のXML構造です..

<?xml version="1.0" encoding="utf-8" ?>
<Document>
  <Class Code="001">
    <Subject Course="Math" AllTeachers='N' SpeciaGuest='N'></Subject>
    <Subject Course="Engish" AllTeachers='Y' SpeciaGuest='Y'></Subject>
    <Subject Course="History" AllTeachers='Y' SpeciaGuest='Y'></Subject>
  </Class>
  <Class Code="002">
    <Subject Course="Math" AllTeachers='Y' SpeciaGuest='N'>
      <Topic Code="1">LAW1</Topic>
      <Topic Code="2">
        LAW2
      </Topic>
      <Topic Code="3">
        LAW3</Topic>
      </Subject>
    <Subject Course="Engish" AllTeachers='Y' SpeciaGuest='Y'></Subject>
    <Subject Course="History" AllTeachers='Y' SpeciaGuest='Y'></Subject>
  </Class>
</Document>

条件を使用して複数の選択結果を選択する方法を教えてください。また、この linq クエリで resharper を使用しても問題ないことをお知らせください。

4

4 に答える 4

1

条件演算子を使用する必要があります。

Children1 = StyCode == 0 ? 
    ltd.Attribute("AllTeachers").Value == "Y"
:
   (ltd.Attribute("SpeciaGuest").Value == "Y"
 || ltd.Elements("Topic").Attributes("Code").Select(a => a.Value).Contains("1")
    )
于 2013-01-21T19:09:37.567 に答える
1

異なるプロパティを持つ匿名オブジェクトを作成することはできません。その場合、シーケンスタイプは何でしょうか? 同じプロパティに異なる値を割り当てることができます (三項演算子を使用?:)

XDocument xdoc = XDocument.Load(@"test.xml");

var lv1s = from c in xdoc.Descendants("Class")
           where (string)c.Attribute("Code") == "002"
           select new {
               Children = (StyCode == 0) ? 
                          ((string)c.Attribute("AllTeachers") == "Y") :
                          ((string)c.Attribute("SpeciaGuest") == "Y") ||
                            c.Elements("Topic")                                 .
                             .Any(t => (string)t.Attribute("Code") == "1"))
           };

ところで、あなたが返しているのは、ブール値のChildrenプロパティを持つオブジェクトのリストです。結果にはより多くのデータが必要だと思います。

于 2013-01-21T19:00:59.640 に答える
1
bool flag = boolexpression ? true : false;

と同じです

bool flag = boolexpression;

したがって、コードを不必要に複雑にするために 3 進数を使用するのはやめてください。


select 句を次のように記述できます。

select new 
{ 
  Children1 = (StyCode==0) ? ltd.Attribute("AllTeachers").Value.Equals("Y") : false,
  Children2 = (StyCode==0) ? false :
     ltd.Attribute("SpeciaGuest").Value.Equals("Y")
     || ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null
}

条件を繰り返すのは悪い形だと言う人もいるかもしれません。あなたがそのキャンプにいる場合は、代わりにこれを使用することをお勧めします。

select (StyCode == 0) ? objectContructor1(ltd) : objectConstructor2(ltd)
于 2013-01-21T19:09:13.017 に答える
1

if(StyCode=0)はシーケンス内の現在のアイテムに基づいていないためif、クエリの外側をプルできます。

Selectまた、両方の句が単一の項目を選択しているため、匿名型は必要なく、その項目を選択するだけであることに注意してください。その結果、次のようになります。

XElement rootElement = XElement.Load(@"test.xml");
int StyCode = 0;
IEnumerable<IEnumerable<bool>> lv1s;
if (StyCode == 0)
{
    lv1s = from lv1 in rootElement.Descendants("Class")
            where lv1.Attribute("Code").Value.Equals("002")
            select (from ltd in lv1.Descendants("Subject")
                    where ltd.Attribute("Course").Value.Equals("Math")
                    select ltd.Attribute("AllTeachers").Value.Equals("Y") ? true : false);
}
else
{
    lv1s = from lv1 in rootElement.Descendants("Class")
            where lv1.Attribute("Code").Value.Equals("002")
            select (from ltd in lv1.Descendants("Subject")
                    where ltd.Attribute("Course").Value.Equals("Math")
                    select ltd.Attribute("SpeciaGuest").Value.Equals("Y") ? true : ltd.Elements("Topic").Attributes("Code").Where(x => x.Value.Equals("1")).FirstOrDefault() != null ? true : false);
}

したがって、これはシンプルで優れていますが、コードの重複が多く、あまり良くありません。下降するもう 1 つの方法は、整数だけでなくXElementを表すを取り、適切な値を示すブール値を返すメソッドを作成することです。書くのは簡単な方法です:ltdStyCode

private static bool GetChildFromSubject(int styCode, XElement subject)
{
    if (styCode == 0)
        return subject.Attribute("AllTeachers").Value.Equals("Y");
    else
    {
        return subject.Attribute("SpeciaGuest").Value.Equals("Y") ||
                subject.Elements("Topic").Attributes("Code")
                .Any(x => x.Value.Equals("1"));
    }
}

ここで必要なクエリは 1 つだけです。

XElement rootElement = XElement.Load(@"test.xml");
int StyCode = 0;
var lv1s = from lv1 in rootElement.Descendants("Class")
            where lv1.Attribute("Code").Value.Equals("002")
            select (from ltd in lv1.Descendants("Subject")
                    where ltd.Attribute("Course").Value.Equals("Math")
                    select GetChildFromSubject(StyCode, ltd));

ずっといい。

于 2013-01-21T19:13:23.387 に答える