[php] xml met variabele opmaak inlezen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Woef
  • Registratie: Juni 2000
  • Niet online
Graag wil ik voor mijn CMS een mogelijkheid maken om xml-bestanden te kunnen inlezen ongeacht wat de opmaak is. Van te voren weet ik niet hoe "diep" de gegevens in het xml-bestand staan. Het kan dus zijn dat op basis van voorbeeld 2 de gegevens staan op $xml->klant maar bij voorbeeld 3 op $xml->klantenbestand->klant. Het is de bedoeling dat de gebruiker de velden zoals "naam" en "straatnr" zelf gaat koppelen aan de velden die beschikbaar zijn binnen het CMS-pakket. Met SimpleXML heb ik een XML ingelezen en getracht de array_keys te verkrijgen maar dat gaat uiteraard niet lukken aangezien SimpleXML een object retour stuurt.
Ik heb er aan gedacht om XSD te gaan eisen, maar weet nu al dat een paar pakketten die niet leveren en om dat nu weer handmatig te gaan maken. Heb al een dag zitten zoeken naar de juiste functies maar helaas niet kunnen vinden.

Concreeet:
  1. Hoe krijg ik alle keys (zoals naam en straatnr)?
  2. Hoe weet ik de diepte daar van?
  3. Enkele tips hoe dit aan te pakken?
voorbeeld 1
code:
1
2
3
4
5
6
<klant>
<naam>Jansen</naam>
<adres type="straatnr">Veldweg 6</adres>
<adres type="postnr">1791</adres>
<adres type="gemeente">Ons Dorp</adres>
</klant>

voorbeeld 2
code:
1
2
3
4
5
6
<klant>
<naam>Jansen</naam>
<straatnr>Veldweg 6</straatnr>
<postnr">1791</postnr>
<gemeente">Ons Dorp</gemeente>
</klant>

voorbeeld 3
code:
1
2
3
4
5
6
7
8
<klantenbestand>
<klant>
<naam>Jansen</naam>
<straatnr>Veldweg 6</straatnr>
<postnr">1791</postnr>
<gemeente">Ons Dorp</gemeente>
</klant>
</klantenbestand>

Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
Ik denk dat je XML verkeerd gebruikt. XML is bedoeld om data op een gestructureerde wijze tussen A en B te bewegen. A en B weten hoe ze de data moeten interpreteren en daardoor kunnen geen misverstanden onstaan.

Wat jij wilt is dat een van beiden gaat gokken hoe de informatie eruit zou kunnen zien. Dat is wel mogelijk, maar niet helemaal de bedoeling van XML.

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

  • Woef
  • Registratie: Juni 2000
  • Niet online
AlainS schreef op dinsdag 24 februari 2009 @ 23:15:
Ik denk dat je XML verkeerd gebruikt. XML is bedoeld om data op een gestructureerde wijze tussen A en B te bewegen. A en B weten hoe ze de data moeten interpreteren en daardoor kunnen geen misverstanden onstaan.

Wat jij wilt is dat een van beiden gaat gokken hoe de informatie eruit zou kunnen zien. Dat is wel mogelijk, maar niet helemaal de bedoeling van XML.
Ja, dat is ook de reden waarom het lastig is om een goede oplossing te vinden. Toch wil ik bovenstaande gaan ontwikkelen. Want met bovenstaande oplossing bespaar ik me een hoop tijd. Anders moet ik namelijk voor elk xml-bestand een import script maken.

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 22:02
Met PHP5 kun je door de zichtbare properties lopen: http://nl.php.net/manual/en/language.oop5.iterations.php

Daarnaast kun je met deze functies je object nog verder ontleden.

Ik begrijp dat je een XML structuur wilt mappen naar je eigen database. Ik vrees dat als je alle rare uitzonderingen wil vangen uiteindelijk veel meer tijd kwijt bent dan een importbestand maken per klant.

Ik persoonlijk zou toch proberen een standaard XML formaat voor te stellen en ze daarmee te laten werken of anders per klant een importscriptje maken.

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Woef schreef op dinsdag 24 februari 2009 @ 23:20:
[...]
Ja, dat is ook de reden waarom het lastig is om een goede oplossing te vinden. Toch wil ik bovenstaande gaan ontwikkelen. Want met bovenstaande oplossing bespaar ik me een hoop tijd. Anders moet ik namelijk voor elk xml-bestand een import script maken.
Tja, je kunt niet verwachten dat je geautomatiseerd elke <street>, <straat> en <straße> vindt- en dan ook nog vaststelt dat het alle drie straatnamen zijn. Bovendien heb je dan nog het soort lullige details als huisnummertoevoeging. Dat kan als <huisnummmer toevoeging="B">3</> maar ook als
<huisnummmer>3B</> of <huisnummmer>3<toevoeging>B</toevoeging></huisnummmer> of <huisnummmer>3</huisnummmer><toevoeging>B</toevoeging>.

Wat jij wil is vermoedelijk een methode om voor elk formaat aan te geven hoe je de straatnaam exporteert. De standaard methode is dan een verzameling XPath expressies. Voor elk document formaat hoef je dan alleen de XPath queries voor straat, huisnummer etc te definieren.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Woef
  • Registratie: Juni 2000
  • Niet online
@MSalters
Als je mijn startpost goed leest, staat er dus ook dat de gebruiker de velden gaat koppelen.
Het is de bedoeling dat de gebruiker de velden zoals "naam" en "straatnr" zelf gaat koppelen aan de velden die beschikbaar zijn binnen het CMS-pakket.
Dus dat probleem is er niet. Alleen het probleem van die toevoegingen wel. Op dit moment zie ik dat probleem nog niet voorkomen, maar het is goed om daar over na te denken.

De oplossing die ik nu heb gemaakt is dat ik het object die ik retour krijg van SimpleXML "cast" (doormiddel van een eigen functie) naar een array. En vervolgens daar de array_keys van pak. Niet mooi, maar werkt wel voor voorbeeld 2 en voorbeeld 3. Dat ga ik dus ook als opmaak-eis stellen. Als iemand een mooiere cq. betere oplossing heeft hoor ik dat graag :).

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

Daar hebben ze dus tools als XQuery voor uitgevonden :) Zie ook w3schools.com als je niet weet hoe dat werkt

  • Woef
  • Registratie: Juni 2000
  • Niet online
MBV schreef op donderdag 26 februari 2009 @ 01:04:
Daar hebben ze dus tools als XQuery voor uitgevonden :) Zie ook w3schools.com als je niet weet hoe dat werkt
Hoe zou ik XQuery dan moeten toepassen voor bovenstaande? Ik ken XQuery maar zou niet weten bij welke van boven genoemde problemen ik dit zou moeten toepassen. Te meer omdat ik niet van te voren weet wat de keynamen zijn.

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

Als je weet wat de tagname is van het data-element(het minste wat een klant kan opgeven) kan je met XQuery zoeken naar een willekeurige node met die naam als child. Als je dan ook aan de klant vraagt welke tagname de elementen groepeert per 'record', dan kan je met XQuery eenvoudig door de lijst van records heen lopen, en steeds de lijst gegevens per record laten geven.

Syntax is een beetje roestig bij mij, maar je zou dan zoiets kunnen doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
$xquery = '
<html><head/><body>
{
  for $record in doc("klantgegevens.xml")//<?php='.$tagname_record.'
  return
    <div>
      <p>{ string($record//'.$tagname_name.') }</p>
      <p>{ string($record//'.$tagname_address.') }</p>
    </div>
}
</body></html>';

Als je dat een beetje slim aanpakt, kan je dus een 'willekeurig' XML-bestand heel snel omzetten naar een gestandariseerd XML-bestand. In XPath zou je volgens mij hetzelfde kunnen doen.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Woef schreef op dinsdag 24 februari 2009 @ 23:20:
Ja, dat is ook de reden waarom het lastig is om een goede oplossing te vinden. Toch wil ik bovenstaande gaan ontwikkelen. Want met bovenstaande oplossing bespaar ik me een hoop tijd. Anders moet ik namelijk voor elk xml-bestand een import script maken.
Je bedoelt een XSLT script, en die zijn enorm simpel. Dat zal sowieso een stuk simpeler zijn dan hier zelf kaas van te proberen te maken, en bovendien is het ook nog eens precies waar XSL voor gemaakt is.

https://niels.nu


  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Inderdaad, XSLT is the way to go. Gebruik intern slechts 1 formaat en zorg er dus voor dat alle formaten die je ontvangt, met XSLT naar dat ene interne formaat worden omgezet. Scheelt je een enorme bak werk en ellende in je programmatuur.
Pagina: 1