Laden...

Für XML Attribut Gleichheit 1 Aktion

Erstellt von xKushGene vor 7 Jahren Letzter Beitrag vor 7 Jahren 1.176 Views
X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 7 Jahren
Für XML Attribut Gleichheit 1 Aktion

Guten Abend.

Ich möchte meine XML Elemente in einer Category geordnet haben. Dazu habe ich als Attribut "subcategory" festgelegt und möchte nun, dass alle Elemente, welche den gleichen Inhalt bei subcategory haben, ein Border bekommen, worin der Name der Subcategory drin steht.

Funktioniert soweit auch. Allerdings wird für jedes Element so ein Border erstellt. Ich möchte nur, dass ein Border für alle Elemente erstellt wird. Als Beispiel habe ich ein Screenshot gemacht.
Derzeit ist das in einer For Schleife (deswegen bekommt auch jedes Element diesen Border).

Mir fällt aber keine passende Schleife dazu ein, wie ich das so regeln kann das jetzt Default Block und Alternative Block in EINEM grassblock Border sind.

Ich glaube nicht, dass while, foreach oder for mir da weiterhelfen können und frage deshalb hier, wie ich das problem am besten lösen könnte.

mfg

4.939 Beiträge seit 2008
vor 7 Jahren

Ich denke, du brauchst eine Verschachtlung:

  1. nach "subcategory" gruppieren
  2. die Items jeder Gruppe zur Kategorie hinzufügen

Welche UI verwendest du denn (WinForms oder WPF)?
Ich tippe mal auf letzteres - wie sieht dann deine XAML und ViewModel dazu aus?

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 7 Jahren

Welche UI verwendest du denn (WinForms oder WPF)?
Ich tippe mal auf letzteres - wie sieht dann deine XAML und ViewModel dazu aus?

Jap. WPF.
Meine XML sieht wie folgt aus:

<Textures>
      <Texture Name="Default Block" Description="The Default Block" TexturePath="Resources/0.png" Selected="true" Default="true" Category="mainblocks" Subcategory="grassblocks"/>
      <Texture Name="Alternative Block" Description="An Alternative Block" TexturePath="Resources/1.png" Selected="false" Category="mainblocks" Subcategory="grassblocks" Default="false" />
      <Texture Name="Default Block STONE" Description="The Default Block" TexturePath="Resources/0.png" Selected="false" Default="true" Category="mainblocks" Subcategory="stone" />
      <Texture Name="Alternative Block STONE" Description="An Alternative Block" TexturePath="Resources/1.png" Selected="false" Default="false" Category="oreblocks" Subcategory="stone" />
</Textures>

Ich habe Category und Subcategory als Attribut gemacht, da ich das mit <Category name="mainblocks"> nicht hinbekommen habe. Also die Daten dann auszulesen. So funktioniert es ja.

Meinst du mit ViewModel den Code um das auszulesen?:

 textureList = (
                 from el in XDocument.Load(@"C:\Users\Kevin\documents\visual studio 2015\Projects\Ragecraft Customizer WPF\mainFrm\Textures.xml").Root.Elements("Texture")
                 where (string)el.Attribute("Category") == "mainblocks"
                 select new Texture
                 {
                     Name = (string)el.Attribute("Name"),
                     Description = (string)el.Attribute("Description"),
                     TexturePath = (string)el.Attribute("TexturePath"),
                     Selected = (bool)el.Attribute("Selected"),
                     Default = (bool)el.Attribute("Default"),
                     Category = (string)el.Attribute("Category"),
                     Subcategory = (string)el.Attribute("Subcategory")
                 }).ToList();
16.834 Beiträge seit 2008
vor 7 Jahren

Zum Umgang mit XML Daten:

Bitte verwende die von XElement und XAttribut zur Verfügung stehenden Eigenschaft Value für das Lesen der Werte und kein (fahrlässiges) casting.
Du solltest Dir abgewöhnen, das über das Casting zu lösen; Du hast an dieser Stelle einfach Glück, dass die Entwickler ToString überschrieben haben und hier Value zurück geben...

3.003 Beiträge seit 2006
vor 7 Jahren

Spätestens an der Stelle würde ich auch nicht mehr von Hand parsen, sondern mein XML in die Zwischenablage tun, als Klasse einfügen, etwas refaktorieren und dann per XmlSerializer arbeiten:


var serializer = new XmlSerializer(typeof(TextureCollection));
TextureCollection collection;

using(var file = File.OpenRead("example.xml"))
using (var reader = XmlReader.Create(file))
    collection = (TextureCollection)serializer.Deserialize(reader);

...und fertig.

LaTino
EDIT: grad mit Stoppuhr in der Hand ausprobiert, Aufwand waren 48 Sekunden inkl. Erstellen der Klassen 😉

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)