[Linq to XML]Moeite met juiste query te maken

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19-09 10:08

Haan

dotnetter

Topicstarter
Wat ik wil is een Dictionary genereren op basis van een xml bestand met de volgende structuur:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<root>
   <entity name="entity1">
      <mapping>
         <source>source1</source>
         <target>target1</target>
      </mapping>
      <mapping>
         <source>source2</source>
         <target>targe2</target>
      </mapping>
    </entity>
    <entity name="entity2">
      <mapping>
         <source>source1</source>
         <target>target1</target>
      </mapping>
      <mapping>
         <source>source2</source>
         <target>targe2</target>
      </mapping>
    </entity>
</root>


In de dictionary komen dan source/target mappings van een enkele entity.

Nu heb ik dat volgens mij op een omslachtige manier gedaan:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
XDocument mappingXml = XDocument.Load("mapping.xml");
Dictionary<string, string> mappings = new Dictionary<string, string>();

var query = from m in mappingXml.Descendants("entity")
        where (string)m.Attribute("name") == "entity1"
        select new
        {
            Mappings = m.Elements("mapping")
        };            

foreach (var v in query)
{
    foreach (XElement xe in v.Mappings)
    {
        mappings.Add(xe.Element("source").Value, xe.Element("target").Value);
    }
}    

De eerste foreach is omdat ik geen makkelijkere manier kon vinden om direct de Mappings property uit de query variabele te krijgen :/

Wat ik eigenlijk zou willen is gewoon direct een select maken waarin ik een Source en een Target zet en dan dus de volgende loop gebruiken:

C#:
1
2
3
4
foreach (var v in query)
{
    mappings.Add(v.Source, v.Target);
}


Daar zit dus het probleem, het beste resultaat dat ik tot nu toe heb bereikt is alleen het eerste element te krijgen met 'Source = m.Element("mapping").Element("Source")'.

Ik ben dus benieuwd of hier een handigere oplossing voor is dan ik nu heb :)

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 20:34

Peetman

Tjah....

Heb niet direct een test beschikbaar, maar misschien is dit handiger:
C#:
1
2
3
4
5
6
7
var mappings = from m in mappingXml.Descendants("mapping")
        select new
        {
            source = m.Elements("source"),
            target= m.Elements("target"),
            entity = m.Ancestor("entity").Attributes("name")
        }; 

En dan die collection in een dictionary gaan stoppen

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19-09 10:08

Haan

dotnetter

Topicstarter
Peetman schreef op vrijdag 24 juli 2009 @ 12:55:
Heb niet direct een test beschikbaar, maar misschien is dit handiger:
C#:
1
2
3
4
5
6
7
var mappings = from m in mappingXml.Descendants("mapping")
        select new
        {
            source = m.Elements("source"),
            target= m.Elements("target"),
            entity = m.Ancestor("entity").Attributes("name")
        }; 

En dan die collection in een dictionary gaan stoppen
Dat is zo te zien niet echt handiger, dan haal je dus alle nodes op, en moet je daarna alsnog handmatig gaan filteren op entiteit. Een Ancestor methode bestaat trouwens niet, en m.Ancestors("entity") geeft geen resultaat terug..

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Niek.NET
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:54
Zoiets:

C#:
1
2
3
4
5
6
7
8
9
10
11
Dictionary<string, Dictionary<string, string>> result; // First key = entity name, second dict, key = source, value = target


result = (from n in doc.Descendants("entity")
          let name = n.Attribute("name").Value
          let mappings = n.Descendants("mapping")
          select new 
          {
            EntityName = name,
            Mappings = mappings
          }).ToDictionary((e => e.EntityName), (e => e.Mappings.ToDictionary(m => m.Element("source").Value, m => m.Element("target").Value)));

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19-09 10:08

Haan

dotnetter

Topicstarter
Die ToDictionary extension method is wel mooi :) Ben alleen nog niet zo goed thuis in hoe die dingen werken.. Dictionary in een Dictionary vind ik niet zo heel mooi, dus ik kom nu uit op dit:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
var query = from m in mappingXml.Descendants("entity")
            where (string)m.Attribute("name") == "entity1"
            let mappings= m.Descendants("mapping")
            select new
            {
                Mapping = mappings
            };

Dictionary<string, string> mapping;
foreach (var v in query)
{
    mapping = v.Mapping.ToDictionary(x => x.Element("source").Value, x => x.Element("target").Value);
}     

Alleen die foreach zou ik nog weg willen werken, dan is het volgens mij wel netjes :)

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Niek.NET
  • Registratie: Oktober 2005
  • Laatst online: 18-09 13:54
Haan schreef op vrijdag 24 juli 2009 @ 14:17:
Die ToDictionary extension method is wel mooi :) Ben alleen nog niet zo goed thuis in hoe die dingen werken.. Dictionary in een Dictionary vind ik niet zo heel mooi, dus ik kom nu uit op dit:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
var query = from m in mappingXml.Descendants("entity")
            where (string)m.Attribute("name") == "entity1"
            let mappings= m.Descendants("mapping")
            select new
            {
                Mapping = mappings
            };

Dictionary<string, string> mapping;
foreach (var v in query)
{
    mapping = v.Mapping.ToDictionary(x => x.Element("source").Value, x => x.Element("target").Value);
}     

Alleen die foreach zou ik nog weg willen werken, dan is het volgens mij wel netjes :)
Maar in die foreach overschrijf je gewoon die mapping var. Wat wil je dat het eindresultaat is dan?

Je zult die mappings op enige wijze moeten groeperen toch?

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19-09 10:08

Haan

dotnetter

Topicstarter
Door de where clausule is het resultaat altijd maar 1 node ;) Daarom is die foreach ook een beetje nutteloos, maar ik kan niet vinden hoe je dat anders doet.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

Verwijderd

Haan schreef op vrijdag 24 juli 2009 @ 14:31:
Door de where clausule is het resultaat altijd maar 1 node ;) Daarom is die foreach ook een beetje nutteloos, maar ik kan niet vinden hoe je dat anders doet.
query.First() of query.Single()

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19-09 10:08

Haan

dotnetter

Topicstarter
Verwijderd schreef op vrijdag 24 juli 2009 @ 15:04:
[...]

query.First() of query.Single()
Thanks! _/-\o_

Kater? Eerst water, de rest komt later

Pagina: 1