XML ismétlődő blokk generálása beolvasáskor

XML ismétlődő blokk generálása beolvasáskor
2008-03-25T10:06:34+01:00
2008-03-25T10:06:35+01:00
2022-11-08T06:35:45+01:00
libor
A probléma: van egy saját szerkezetű xml fájlom, ami egy program paramétereit tartalmazza:
<?xml version="1.0" encoding="utf-8" ?> <scada> <dataitem id="aram" type="ushort" desc="áramfelvétel"> <plc pos="12" mode="poll" /> </dataitem> <repeat id="1,2,3" desc="1-es, 2-es, 3-as"> <dataitem id="motor*" type="byte" desc="* motor állapota"> <plc pos="30" mode="poll" /> </dataitem> </repeat> </scada>

a 'repeat' elem célja, hogy a benne levő gyerekelemek ismétlődjenek a beolvasáskor, úgy, hogy a '*' placeholder rendre a megadott listával töltődjön fel az attributumok értékeiben.

Csináltam rá egy extension metódust, működik is, de csak egy szint mélyen tudok vele beleírni az attributumok tartalmába. (a gyerekelemek attributumaihoz már nem nyúlok)
Nem akartam fixen bedrótózva megírni (úgy ment volna persze), hogy hány szint mély legyen, általánosra akarom megirni (tetszőlegesen mély elemhierarchia esetére), tehát úgy sejtem, valami rekurzív megközelítés kéne, csak ahhoz már nem volt elég agysejtem a logikai ügyosztályon
Valaki ránézne ?

Szóval itt a RepeatElements nevű extension metódusom egy működő példaprogramban. (egy kis LINQ-esítés is valszeg jót tenne a dolognak)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; namespace XmlProba { class Program { static void Main(string[] args) { XElement xroot = XElement.Load("proba.xml"); var dataitems = xroot.RepeatElements(); foreach (XElement xe in dataitems) { Console.WriteLine(xe.ToString()); } Console.ReadLine(); } } public static class MyXmlUtils { public static IEnumerable<XElement> RepeatElements(this XElement xf) { foreach (XElement xe in xf.Elements()) { if (xe.Name.ToString() != "repeat") { yield return xe; continue; } var repeatrules = xe.Attributes(); Dictionary<string, string[]> repdict = new Dictionary<string, string[]>(repeatrules.Count()); foreach (XAttribute xa in repeatrules) { repdict.Add(xa.Name.ToString(), xa.Value.Split(',')); } var xes = xe.Elements(); int rulesLength = 0; foreach (string[] val in repdict.Values) { rulesLength = val.Length; break; } for (int i = 0; i < rulesLength; i++) { foreach (XElement xrep in xes) { var attribs = xrep.Attributes(); XElement newxe = new XElement(xrep); foreach (XAttribute attrib in attribs) { string attname = attrib.Name.ToString(); if (repdict.ContainsKey(attname)) { string[] repvals = repdict[attname]; newxe.SetAttributeValue(attname, newxe.Attribute(attname).Value.Replace("*", repvals[i])); } } yield return newxe; } } } } } }

Másik, apró kérdés:
Ha van egy Dictionary<string, string[]> repdict változóm, akkor milyen szintaxissal férek hozzá egy eleméhez: a repdict["kulcs"].[index]-re hibát ad, csak kettébontva tudtam beleírni.
Szerk: ..izé, bocs.. erre közbe rájöttem, nem kell a pont.


Másik kérdés:
Hogy hívom elő egy Dictionary 'tökmindegyhogymelyik' elemét, anélkül hogy ismernék benne egy kulcsot is ? Most ezt így oldottam meg, de gondolom, nem túl elegáns:
int rulesLength = 0;
foreach (string[] val in repdict.Values) { rulesLength = val.Length; break; }
Mutasd a teljes hozzászólást!

Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd