» »

[C++] Pridobitev podatkov iz XML

[C++] Pridobitev podatkov iz XML

Greek ::

Pozdravljeni,

Delam na eni aplikaciji, sedaj se mi je zataknilo, prosim za kak namig ali nasvet. Iz drugih datotek dobim med besedami različne podatke, naprimer številko ali podatek v obliki 12:0. (XML je taki kot je, nemorem ga spreminjati, je velik in dolg, indeksi imen grup niso po vrsti, ker če spremenim lastnosti tipke ali jo izbrišem nastane "luknja" v indeksih, torej izhajati moram iz takega xmlja zaenkrat kot pač je). K eni tipki spadata dva group sklopa lastnosti, saj se vidi v spodnjem izseku, torej spodnji izsek je za dve tipki lastnosti.
Če dobim naprimer podatek številko 12345, rabim še iz xmlja podatke ime (PRIMER1 Številka) in ime te grupe (coApp). Te podatke potem moram spet uporabiti v drugih datotekah.

Lahko pa dobim tudi podatek iz ene od datotek, naprimer 12:0. To mi pove vrednosti module( < param name="module" value="12"/> : id (< param name="id" value="0"/> (podatek dve vrstici višnje). Torej iz teh podatkov moram potem spet pridobiti ime grupe (spodnje grupe, torej nekaj vrstic nižje "Coapp"), ime ("PRIMER1 Številka") in številko (12345).
Ali naprimer dobim v eni datoteki podatek 1:19, potem rabim iz tega izseka xmlja podatke ("Con", Sestavi, 1234567), ter te pripisati podatku 1:19 v drugi datoteki.

Nevem kako se lotiti kaj takega. Imam nekaj idej vendar nevem če bodo šle v pravilno smer. Lahko bi seveda ročno parsal podatke, vendar pri velikem xmlju je to nesmiselno pomojem. Mogoče bi lahko kako xml shranil v kako strukturo ali razred? Struktura bi imela lastnosti naprimer int module, int id, string ime_grupe, string ime, int stevilka? In potem bi črpal druge podatke od te tipke, če bi imel podanega samo enega?

Hvala v naprej vsem za nasvete.


<?xml version="1.0" encoding="utf-8" ?>
<settings version="1.0">
<group  name="Map" id="0">
  <param name="version" value="v3.0"/>
  <group  name="Map" id="1">
    <group  name="objectPair" id="2">
      <group  name="appPosition" id="3">
        <param name="id" value="0"/>
        <param name="level" value="0"/>
        <param name="module" value="12"/>
        <param name="posx" value="4"/>
        <param name="posy" value="4"/>
      </group>
      <group  name="coApp" id="4">
        <param name="name" value="PRIMER1 Številka"/>
        <param name="number" value="12345"/>
        <param name="addnumber" value=""/>
        <param name="account" value="-1"/>
      </group>
    </group>

    <group  name="objectPair" id="5">
      <group  name="appPosition" id="6">
        <param name="id" value="19"/>
        <param name="level" value="0"/>
        <param name="module" value="1"/>
        <param name="posx" value="172"/>
        <param name="posy" value="340"/>
      </group>
      <group  name="Con" id="7">
        <param name="name" value="Sestavi"/>
        <param name="number" value="1234567"/>
        <param name="account" value="-1"/>
      </group>
    </group>

Greek ::

Noben?

DuleKrtola ::

milc ::

Uporabi LibXML - http://www.xmlsoft.org/
Potem pa z XPath-i prideš do želenih podatkov in sicer tako:
XPath za
1. //group/param[@name='number' and @value='12345']/../param[@name='name']/@value
2.1 //group/param[@name='module' and @value='12']/../../group[@name='coApp']/param[@name='name']
2.2 //group/param[@name='module' and @value='12']/../../group[@name='coApp']/param[@name='number']

Ostale si pa sam sestavi.

Tko na hitro si lahko pomagaš s http://www.xpathtester.com/test.

Ko si enkrat v svetu xmlj-ev, pozabi na tri vrstice gor ali pa dol. Parsanje z lastno kodo je za res zelo, zelo dobre. Za ostale pa so super knjižnice kot je LibXML.

PS: Pa skopiral si nepopoln xml. Manjka /group in /settings.

Zgodovina sprememb…

  • spremenil: milc ()

Greek ::

Najprej hvala za odgovore.
@milc
Ja, pozabil sem prikopirati zadnje dve znački, ki zapirata < settings version="1.0"> in < group name="Map" id="0">.

Drugače pa je to področje zame popolnoma novo, zato se ne znajdem najbolj. Pač ena dumy ideja, ki jo imam je, da bi mogoče z getline šel vrstico po vrstico, iskal ključne besede, ki me zanimajo (zanimali me bodo vedno sledeče značke ki so spodaj v kodi) in potem s substringi izluščil te podatke iz značk, ter jih shranjeval v kako strukturo.

Verjetno pa so veliko bolj elegantne rešitve možne, če se vključi v projekt kak free parser. Kot povedano, parsanje xmlja v C++ je popolnoma novo področje zame.

Torej pri prvem me zanima (seveda samo izluščene vrednosti, ne cele značke):
<param name="id" value="0"/>
<param name="module" value="12"/>
<group  name="coApp" id="4">
<param name="name" value="PRIMER1 Številka"/>
<param name="number" value="12345"/>


in naprimer pri drugem gumbu:


<param name="id" value="19"/>
<param name="module" value="1"/>
<group  name="Con" id="7">
 <param name="name" value="Sestavi"/>
<param name="number" value="1234567"/>



Za vsako tipko bom imel le en podatek iz drugih datotek, ki si ga izluščim (podatek number, torej naprimer 12345) ali največ dva podatka (dva v primeru module (naprimer 1) in id (naprimer 19) ), drugih podatkov nikoli ne bom imel iz drugih datotek. Torej recimo < group name="Con" id="7"> nikoli ne bom vedel iz drugih datotek, moral pa bom ta podatek dobiti ali na podlagi number (ki je v isti skupinici) ali pa module in id, ki sta v zgornjem sklopu.

torej če sem prav razumel xpathe, potem žal ta dva naprimer nikoli ne prideta za mene v poštev, saj group name nebom poznal (v tem primeru group[@name='coApp']), najti ga moram iz number ali pa (odvisno od primerov) iz module in id.
2.1 //group/param[@name='module' and @value='12']/../../group[@name='coApp']/param[@name='name']
2.2 //group/param[@name='module' and @value='12']/../../group[@name='coApp']/param[@name='number']


Poskušal sem vključit libxml, vendar mi ne uspe. Ali je mogoče stvar rešiti tudi s kakšnim RapidXML ali TinyXML parserji? Gre se mi, da na čimlažji način pridobim te podatke iz xmlja, ter jih naknadno uporabljam spet. Torej verjetno s kakim parserjem, ki bo bral takšno strukturo xmlja in s shranjevanjem v kako strukturo ali class, če prav razumem problem?

Hvala v naprej in lep dan!

Zgodovina sprememb…

  • spremenil: Greek ()

keworkian ::

Prvi xpath
//settings//group//group//group
,
dobis nodeset loopaš čez nodeset in greš čez
nodeset->children->next


potem pa samo uporabljaš
if (xmlStrCmp(node->name, (xmlChar*)"param"))


Je čisto preprosto :)
Obscenities in B-Flat


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Davčne blagajne (strani: 1 2 3 424 25 26 27 )

Oddelek: Programiranje
1344332625 (72628) Macketina
»

Powershell primerjaj in kopiraj

Oddelek: Programiranje
61056 (693) Blisk
»

[SQL] - združitev glede na iste vrednosti

Oddelek: Programiranje
131398 (1040) tx-z
»

getElementsByTagName ne dela v Chromu

Oddelek: Programiranje
141680 (1418) win64
»

[stari dobri C] Kako sparsati XML?

Oddelek: Programiranje
101577 (1330) Apple

Več podobnih tem