2010-12-07 5 views
1

J'ai le XML suivant et j'ai besoin d'une requête qui va extraire l'année et le Return_Value lorsque vous passez à travers une statistique spécifique.Comment avez-vous 2 where where dans une instruction xml linq

Le code actuel ne fonctionne pas car vous ne pouvez pas avoir deux clauses where dans une instruction add pour un objet dictionnaire. Y a-t-il une solution à cela?

foreach (var row in rows) 
{ 
    myHoldingsDistribution.Add(row.Descendants() 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName) 
          .Select(q => q.Value).Max()) * multiplier); 

<Table> 
    <Year>1</Year> 
    <Statistic>0 Percentile</Statistic> 
    <Return_Value>0.0535644000000</Return_Value> 
</Table> 
    base {System.Xml.Linq.XContainer}: <Table> 
    <ALMRunResults_Year>1</ALMRunResults_Year> 
    <Statistic>0 Percentile</Statistic> 
    <Return_Value>0.0535644000000</Return_Value> 
</Table> 

FirstAttribute: null 
    HasAttributes: false 
    HasElements: true 
    IsEmpty: false 
    LastAttribute: null 
    Name: {Table} 
    NodeType: Element 
    Value: "10 Percentile0.0535644000000" 

Modifier

Dans la déclaration suivante - Je veux idéalement deux fois pour .Lorsque filtrer ceux qui ne sont pas 1 Centile.

myHoldingsDistribution.Add(row.Descendants() 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     Double.Parse(row.Descendants().Where(y => y.Name.LocalName == valueName) 
          .Select(q => q.Value).Max()) * multiplier); 
+0

Que voulez-vous dire « Vous ne pouvez pas avoir deux clauses où? » Quelle erreur obtenez-vous du code que vous avez fourni? – StriplingWarrior

+0

"Je voudrais idéalement, ailleurs, filtrer deux fois ceux qui ne sont pas 1 percentile." - Et qu'est-ce qui t'arrête? Vous pouvez généralement juste enchaîner les instructions .Where ensemble: 'rows.Where (...). Où (...)' Que se passe-t-il lorsque vous essayez ceci, et à quoi ressemble le code? – StriplingWarrior

Répondre

2

Je suis vraiment très confus par votre requête LINQ, et il semble que le comportement que vous décrivez dans le premier paragraphe ne reflète pas vraiment ce que votre code essaie de faire. Je crois que le problème que vous rencontrez avec votre code a plus à voir avec la mise en place de votre méthode de Double.Parse que toute autre chose, parce que le code suivant compile et fonctionne très bien:

var myHoldingsDistribution = new Dictionary<object, object>(); 
var rows = new[] {new {Descendants = new[]{new {Name = new {LocalName = "test"}, Value = 0.05}}}}; 
var keyName = "test"; 
var valueName = "test"; 
var multiplier = 2d; 
foreach (var row in rows) 
{ 
    myHoldingsDistribution.Add(row.Descendants 
     .Where(y => y.Name.LocalName == keyName) 
     .Select(q => q.Value).Max(), 
     row.Descendants.Where(y => y.Name.LocalName == valueName) 
         .Select(q => q.Value).Max() * multiplier); 

} 

Modifier

Je suis encore très confus par cette question. Jusqu'à présent, vous avez donné les exigences suivantes:

  1. ont 2 où les clauses dans une déclaration xml LINQ
  2. ont deux ou clauses dans une instruction add pour un objet dictionnaire
  3. SELECT * FROM mon jeu de données
  4. filtrer ceux qui ne sont pas 1 Percentile

Je vais ignorer les deux premiers parce que je ne pense pas qu'ils sont nécessaires. La troisième exigence est relativement simple, en supposant que votre format de données est quelque peu fixe. (Avez-vous vraiment dire d'avoir une étiquette « année » et une étiquette « ALMRunResults_Year »?)

// Move the data into an object that can easily be manipulated. 
var transform = from r in rows 
       select new 
       { 
        key = r.Element(keyName).Value, 
        value = Double.Parse(r.Element(valueName).Value), 
        statistic = r.Element(statisticName).Value 
       }; 

Une fois que vous avez sélectionné des valeurs comme ça, vous pouvez simplement utiliser LINQ aux objets pour exécuter le filtre que vous étiez décrire, et de créer un dictionnaire de la collection résultant avec un appel à ToDictionary:

var myHoldingsDistribution = transform 
    // Filter out anybody that's not 1 percentile 
    .Where(r => r.statistic == statisticFilter) 
    // Create a dictionary out of the keys and values 
    .ToDictionary(r => r.key, r => r.value); 

les deux blocs de code je vous ai donné compilez et exécutez très bien compte tenu de la configuration suivante:

var text = 
@"<Root> 
    <Table> 
     <ALMRunResults_Year>1</ALMRunResults_Year> 
     <Statistic>0 Percentile</Statistic> 
     <Return_Value>0.0535644000000</Return_Value> 
    </Table> 
    <Table> 
     <ALMRunResults_Year>2</ALMRunResults_Year> 
     <Statistic>1 Percentile</Statistic> 
     <Return_Value>0.0535644000000</Return_Value> 
    </Table> 
</Root>"; 
var doc = XDocument.Parse(text); 
var rows = doc.Descendants("Table"); 

var keyName = "ALMRunResults_Year"; 
var valueName = "Return_Value"; 
var statisticName = "Statistic"; 
var statisticFilter = "1 Percentile"; 

Est-ce que cela a du sens?

Modifier 2

OU statistique seulement = "0 percentile, 25 percentile, 50 percentile, 75 percentile" etc

Alors, quand vous parlez de 2 où les clauses, vous vouliez dire que vous voulez "où percentile = 0 ou percentile = 25", par exemple? Il y a quelques façons de le faire. Le plus simple est probablement en utilisant la méthode Contains:

var statisticFilters = new[]{ 
    "0 Percentile", "25 Percentile", "50 Percentile", "75 Percentile" 
}; 
... 
var myHoldingsDistribution = transform 
    .Where(r => statisticFilters.Contains(r.statistic)) 
    .ToDictionary(r => r.key, r => r.value); 
+0

Fondamentalement, je veux SELECT * FROM mon ensemble de données – user533978

+0

WHERE Statistique uniquement = "0 percentile, 25 percentile, 50 centile, 75 percentile" etc et ignorer tous les autres balises comme un "99 centile" etc – user533978

+0

@ user533978: Voir mes modifications . – StriplingWarrior