Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Giovanna 19. 04. 2015, 18:12:56
-
Dobry den, mam vlastní objektovou nastavbu nad konfiguracnim souborem, který obsahuje root, rodice, deti, hodnotove elementy atd. Chtel jsem se pridrzet alespoň trochu implementaci podle DOM, proto jsem chtěl podle xpath najit element odpovídající tomuto vyrazu. Proto mam:
public CfgNode SelectValueNode(CfgNode cfgNode, string nodePath, int indexInPath)
{
CfgNode retNode = null;
string nodeInPath = string.Empty;
char[] nodesSeparator = {'/'};
string[] nodesNames = nodePath.Split(nodesSeparator);
if (nodesNames.Length > indexInPath)
{
nodeInPath = nodesNames[indexInPath];
}
if (cfgNode.HasChildren)
{
foreach (CfgNode childNode in cfgNode.ChildNodes)
{
if ((childNode.nodeName != string.Empty) && (childNode.nodeName == nodeInPath))
{
Console.WriteLine(childNode.nodeName);
retNode = SelectValueNode(childNode, nodePath, indexInPath + 1);
}
}
}
return retNode;
}
Jenze rekurze to nevyresila(zda se mi) - pral jsem si, aby mi byl vracen pozadovany element - tedy ten na konci xpath cesty za posledním lomítkem. Jenze jsem se v tom ztratil a ted uz si ani nejsem jisty, zda-li rekurze byla dobrym napadem.
Proto jsem se vas chtěl zeptat, zda-li jset to uz resili a jak? Dekuji
-
A jak bys to chtěl řešit??? Modlenim se k bohu??? Prostě musíš projít strom. A to bez cyklu nejde. A je jedno jestli použiješ iterační či rekurzivni variantu. S rekurzi to budeš mít lehčí.
-
Já ale vím, že to celé musím projít i že mám minimálně možnost rekurze. Ale teď nevím jak vrátit a uložit návratovou hodnotu z posledního volání SelectValueNode z rekurze. Nebo to mám dobře a jen někde drobná chybka? Děkuji
P.S. Kdybych to byl ochotný řešit prasácky, tak si nalezený element uložím do statické proměnné typu CfgNode a rekurze už nějak doběhne.
-
1) rekurze je dobry nastroj
2) prehnane pouzivani statickych promennych v OOP je spatne
-
Já ale vím, že to celé musím projít i že mám minimálně možnost rekurze. Ale teď nevím jak vrátit a uložit návratovou hodnotu z posledního volání SelectValueNode z rekurze.
Returnem...
-
Skus si najprv implementovat fibonaciho alebo nieco lahsie. :-X (a ano da sa to aj bez rekurze)
-
(v Javě se nevyznám, jestli je to vůbec Java :))
ale já bych první v třídě cfgNode implementoval metodu childByName
a pak napsal něco jako (pseudokód)
foreach name in nodeNames{
if not(childNode.childByName(name)) {return};
childNode=childNode.childByName(name)
}
return childNode
-
Pořád mi není jasné: Proč nepoužiješ XPath? Nebudeš potřebovat ani rekurzi, ani cyklus.
-
(v Javě se nevyznám, jestli je to vůbec Java :))
ale já bych první v třídě cfgNode implementoval metodu childByName
a pak napsal něco jako (pseudokód)
foreach name in nodeNames{
if not(childNode.childByName(name)) {return};
childNode=childNode.childByName(name)
}
return childNode
To spis vypada na C#, Java to neni urcite
-
To spis vypada na C#, Java to neni urcite
beru na vědomí. já jen poznal, že to není Perl :)
-
To spis vypada na C#, Java to neni urcite
Podle přiblblého zápisu ob řádek bych také tipl C#.
-
To spis vypada na C#, Java to neni urcite
Podle přiblblého zápisu ob řádek bych také tipl C#.
co ma preboha ob radek spolocneho s C# ?
-
Je to C#, akorát v tom foreach po nalezeni node mi chybi break. a dodělat logiku.
Udelam si tam trasovani, zítra je taky den. Asi za 4 minuty.:-)
Diky
Honza
-
Pořád mi není jasné: Proč nepoužiješ XPath? Nebudeš potřebovat ani rekurzi, ani cyklus.
Protože implementuju vlastní formát souboru, který není zcela kompatibilní s XML.
-
malá úprava a kód funguje, jen na začátek metody patří:
CfgNode retNode = cfgNode;
Předtím jsem tam dosazoval null.
Diky vsem.
-
Protože implementuju vlastní formát souboru, který není zcela kompatibilní s XML.
soubor bud je nebo neni xml.
to je chyba zacatecniku, ze hned zacne vymyslet
Vlastni format a pak ma prace nad hlavu s parserem.
-
Podle přiblblého zápisu ob řádek bych také tipl C#.
co ma preboha ob radek spolocneho s C# ?
Je to zlozvyk zejména u programátorů v C#, který v jiných jazycích není tak častý.
-
Pořád mi není jasné: Proč nepoužiješ XPath? Nebudeš potřebovat ani rekurzi, ani cyklus.
Protože implementuju vlastní formát souboru, který není zcela kompatibilní s XML.
Tak to je jednoduché: Udělej ten svůj vlastní formát tak, aby byl zcela kompatibilní s XML.
-
malá úprava a kód funguje, jen na začátek metody patří:
CfgNode retNode = cfgNode;
Předtím jsem tam dosazoval null.
Diky vsem.
Ten kód je na můj vkus málo přehledný. Rekurze se většinou v takovýchto případech dělá tak, že funkce má dvě možné větve: buď jsem našel, co jsem hledal, tak to vrátím (normálním returnem, jak psal Kit), nebo jsem to nenašel, takže jdu hlouběji (rekurze). Čili žádné pomocné proměnné "retNode", žádné jejich nastavování někde uvnitř podmínek a vracení někde úplně jinde. Prostě jenom if(je_to_to_co_hledam(x)) return x; To je celé, nehledat v tom složitosti (andyho rada vyzkoušet si fibonacciho není vůbec od věci).
Tvůj případ je jednoduchý v tom, že hledáš jeden konkrétní uzel, takže ho pohodlně můžeš vrátit returnem. Pokud bys potřeboval např. po celém stromu posbírat uzly, které mají nějakou vlastnost, potřeboval bys akumulátor a bylo by to mírně složitější, ale v tom tvým případě je to snadný.
-
Jo a ještě jeden námět k zamyšlení: pokud hledám ve stromu nějaký uzel pomocí cesty, je většinou dobrý neporovnávat pořád celou cestu, ale porovnávat jenom první položku cesty a při každé rekurzi ji odstřihnout a dál propagovat jenom ten ocas, protože o tom začátku už víš, že sedí, tak ho nemusíš porovnávat pořád dokola. Nějak takhle:
if (childNode.name == prvni polozka cesty) {
if (zadna dalsi polozka) return childNode;
rekurze(childNode,cesta bez prvni polozky);
}
-
Na praci s listy je dobry prolog, tam se pracuje jen s head listu a zbytek je tail listu. A v dalsim kroku rekurze se zas z puvodniho
tailu stane list a zas se to rozsekne na head a tail. A furt dal.
-
Na praci s listy je dobry prolog, tam se pracuje jen s head listu a zbytek je tail listu. A v dalsim kroku rekurze se zas z puvodniho
tailu stane list a zas se to rozsekne na head a tail. A furt dal.
Na to není potřeba prolog, takhle je to i ve všech funkcionálních jazycích. A v nefunkcionálních se to dá použít taky, akorát obvykle ne tak jednoduše.
-
Protože implementuju vlastní formát souboru, který není zcela kompatibilní s XML.
soubor bud je nebo neni xml.
to je chyba zacatecniku, ze hned zacne vymyslet
Vlastni format a pak ma prace nad hlavu s parserem.
Je to tim, ze jsem prisel do firmy a nemuzu jim ze sve pozice rict, předělejte cfg soubory na xml a co xml neumi, to zahodte.
-
Je to tim, ze jsem prisel do firmy a nemuzu jim ze sve pozice rict, předělejte cfg soubory na xml a co xml neumi, to zahodte.
Jenom tak ze zvědavosti: a co tam používáte, že by to něšlo pomocí XML? Nebo jsi to myslel opačně? Že používáte nějaký jazyk/nástroj, který neumí pracovat s XML? Každopádně ať tak nebo tak, docela by mě zajímalo, o co jde, protože zpracování XML je dneska už skoro jako umět spojit dva řetězce ;)
-
Jsem externista a nevim vse, ale podmínkou(delam agregator pro zmenu hodnot v konfiguracích na ruznych mistech) bylo, ze at xml, cfg, nebo ini soubor atd. (do budoucna) musí zustat absolutne beze zmeny vcetne zakomentovane historie - není problém najit v konfiguraku, který není xml, zakomentovane nastaveni hodnot s komentářem na konci = historie nastaveni / backup. Jenom me napadlo, ze XmlDocument bych mohl pouzit pro ulozeni a zmenu hodnot, pokud bych napr. udelal potomka z XmlElement a dodal si tam ty dodatecne věci. Ted mam hotovou a funkcni tridu na 250 radek a zachovavam format.
Co Vy na to?
-
Ještě jeden dotaz, prosím.
Kdybyste museli souhlasit s tím, že už ty cfg soubory existují, uvažovali byste o použití regulárního výrazu pro vyhledání proměnné místo parseru?
Příklad cfg souboru, hloubka stromu není znama:
Root
{
ElementA
{
a = 1 # nejaky komentar
#a = 0 #puvodni hodnota zakomentovana
}
ElementB
{
ElementB1
{
... další nastaveni promennych
...
}
ElementB2
{
...
...
}
}
...
}
Děkuji
-
Kdybyste museli souhlasit s tím, že už ty cfg soubory existují, uvažovali byste o použití regulárního výrazu pro vyhledání proměnné místo parseru?
Ne, protože to není regulární jazyk, čili to regulárním výrazem parsovat nejde. Viz http://cs.wikipedia.org/wiki/Chomsk%C3%A9ho_hierarchie
-
http://stackoverflow.com/a/1732454/1064809