Je ne sais pas comment je suis censé faire ça.

Voici le XML avec lequel je travaille:

<configuration>
    <tag1>
        <interestingstuff>avalue</interestingstuff>
    </tag1>

    <tag2>
         <item_type1 name="foo">
             <item_type2 name="bar">
                 <property>value1</property>
                 <property>value2</property>
             </item_type2>
             <item_type2 name="pub">
                 <property>valueX</property>
                 <property>valyeY</property>
             </item_type2>
          <item_type1>

          <item_type1 name="foo2">
              <item_type2 name="pub">
                  <property>valueX</property>
              </item_type2>
          </item_type1>
      </tag2>
</configuration>

J'écris une fonction qui transmet une valeur pour item_type et item_type2, et renvoie la liste des valeurs de propriété pour cette combinaison.

Voici ce que j'ai. Il lève une exception «Objet non défini sur une instance d'un objet» au point noté.

ArrayList properties = new ArrayList();
XDocument config = new XDocument();
config = XDocument.Parse(XML_Text);
foreach (XElement item1 in config.Root.Element("tag2").Nodes())
{
    if (item1.Attribute("name").Value.ToString() == passed_item1_value)
    {
      //this is where it's breaking
      foreach (XElement item2 in item1.Elements("item_type2").Nodes())
      {
        if item2.Attribute("name").Value.ToString() == passed_item2_value)
        {
           foreach (XElement property in item2.Elements("property").Nodes())
           {
             properties.Add(property.Value.ToString());
           }
           break;
         }
       }
       break;
     }
}

JE SAIS que cela n'a pas de sens - mais je ne peux pas donner de sens.

3
Gregory Sloan 25 janv. 2017 à 11:08

4 réponses

Meilleure réponse

Je le ferais de cette façon:

public IEnumerable<string> findValues(string item1, string item2)
{
    config = XDocument.Parse(XML_Text)
    var res = config.Descendants("item_type1")
                    .Where(x=>x.Attribute("name").Value == item1)
                    .Descendants("item_type2")
                    .Where(x=>x.Attribute("name").Value == item2);
    return res.Descendants("property").Select(x=>x.Value);
}
3
Maksim Simkin 25 janv. 2017 à 08:15

Au cas où un VB'er aurait besoin d'aide pour quelque chose de similaire

    Dim xe As XElement
    xe = <configuration>
             <tag1>
                 <interestingstuff>avalue</interestingstuff>
             </tag1>

             <tag2>
                 <item_type1 name="foo">
                     <item_type2 name="bar">
                         <property>value1</property>
                         <property>value2</property>
                     </item_type2>
                     <item_type2 name="pub">
                         <property>valueX</property>
                         <property>valyeY</property>
                     </item_type2>
                 </item_type1>

                 <item_type1 name="foo2">
                     <item_type2 name="pub">
                         <property>valueX</property>
                     </item_type2>
                 </item_type1>
             </tag2>
         </configuration>

    Dim passed_item1_value As String = "foo" 'for test
    Dim passed_item2_value As String = "pub" 'for test

    Dim ie As IEnumerable(Of String)
    ie = (From el In xe.<tag2>.<item_type1>...<item_type2>
          Where el.Parent.@name = passed_item1_value AndAlso el.@name = passed_item2_value
          From sel In el...<property> Select sel.Value)

    Return ie.ToArray
0
Manfred Radlwimmer 25 janv. 2017 à 13:13

Je suppose que vous voulez quelque chose avec la requête XPath comme suit:

var path = string.Join("/", 
    "configuration",
    "tag2",
    string.Format("item_type1[@name='{0}']", passed_item1_value),
    string.Format("item_type2[@name='{0}']", passed_item2_value),
    "property");

var elements = (IEnumerable)config.XPathEvaluate(path);

var properties = elements.Cast<XElement>().Select(x => x.Value);

N'oubliez pas d'inclure using System.Xml.XPath; ici est XPathEvaluate défini.

1
Mikhail Tulubaev 25 janv. 2017 à 08:46
using System.Linq;
using System.Xml.Linq;

IEnumerable<string> GetProperties(XElement xml, string item1, string item2)
{
    return xml.Element("tag2")
        .Elements("item_type1").Where(x => x.Attribute("name").Value == item1)
        .Elements("item_type2").Where(x => x.Attribute("name").Value == item2)
        .SelectMany(x => x.Elements("property").Select(p => p.Value));
}

Similaire à la plupart des solutions ci-dessus, mais utilise un chemin direct vers les données et utilise SelectMany pour transformer le résultat en une seule collection - c'est-à-dire fonctionnera si vous avez des doublons pour item1 et item2.

1
TVOHM 25 janv. 2017 à 11:08