[ALG] xPath & xmlns (Namespaces)

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 22:44
Hallo,

Dit is een beetje een 'verbastering' van dit topic: \[OBJ-C] [TouchXML] Maps API xPath geeft nooit resultaat waar ik vast kwam te zitten omdat ik geen resultaat terug kreeg van de google maps api (ik kreeg wel resultaat maar ik kon via xPath de nodes niet selecteren).

Omdat ik het probleem heb weten terug te dringen tot een 'algemeen' probleem (niet zo zeer een obj-c probleem) heb ik dit nieuwe topic gestart, zodat ook mensen die geen ervaring hebben met obj-c kunnen helpen.

Het punt was dus dat ik via xpath in sommige xml documenten wel wat kon selecteren, en soms niet. Nu had ik beide documenten naast elkaar gelegd, en in het document waar het niet werkte kwam een aantal keer het 'xmlns' attribuut voor, hierop gegooglde en dit bleken xml namespaces te zijn.

Ik toen verder gaan kijken hoe je met xpath items in een namespace kon selecteren maar ik kon daar niet uitkomen.

Nu is mijn vraag, in bijvoorbeeld dit document:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<kml><Response>
  <name>Dokkum</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">

    <address>Dokkum, The Netherlands</address>
    <AddressDetails Accuracy="4"><Country><CountryNameCode>NL</CountryNameCode><CountryName>The Netherlands</CountryName><AdministrativeArea><AdministrativeAreaName>Friesland</AdministrativeAreaName><Locality><LocalityName>Ee</LocalityName><DependentLocality><DependentLocalityName>Dokkum</DependentLocalityName></DependentLocality></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="53.3385487" south="53.3118913" east="6.0316879" west="5.9676583" />
    </ExtendedData>
    <Point><coordinates>5.9996731,53.3252221,0</coordinates></Point>

  </Placemark>
</Response></kml>


Zitten geen namespaces en kan ik bijvoorbeeld de eerste name selecteren door bijvoorbeeld

code:
1
//coordinates


als xpath te gebruiken en deze geeft dan de coordinaten terug

Maar nu er namespaces in zitten (zie dit document) hoe kan ik dan de betreffende items selecteren? (zelfde xpath query geeft geen resultaat)

(in regel 2 en 11 bevinden zich de xmlns tags in dit geval, dat is het enige verschil met beide documenten)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>Dokkum</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">

    <address>Dokkum, The Netherlands</address>
    <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>NL</CountryNameCode><CountryName>The Netherlands</CountryName><AdministrativeArea><AdministrativeAreaName>Friesland</AdministrativeAreaName><Locality><LocalityName>Ee</LocalityName><DependentLocality><DependentLocalityName>Dokkum</DependentLocalityName></DependentLocality></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="53.3385487" south="53.3118913" east="6.0316879" west="5.9676583" />
    </ExtendedData>
    <Point><coordinates>5.9996731,53.3252221,0</coordinates></Point>

  </Placemark>
</Response></kml>

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 10-08 02:59

Gerco

Professional Newbie

XPath kan ook gewoon namespaces gebruiken, dus je kunt je expressie gewoon zo schrijven:

//kml:coordinates

Je moet natuurlijk wel je XPath evaluator nog uitleggen dat je namespace prefix "kml" graag wilt koppelen aan de namespace uri "http://earth.google.com/kml/2.0". Dat is in dit geval niet het document te halen, want "http://earth.google.com/kml/2.0" is de default namespace van dat document.

In Java moet je dat met een NamespaceContext object doen. Van objective-c weet ik het niet, maar dat zul je vast op een soortgelijke manier moeten doen. Je moet de namespaces die je wilt gebruiken dus eerst registreren bij je xpath evaluator en er een prefix aan koppelen. Dan kun je daarna in je xpath expressie die prefixes gebruiken.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 06-09 16:59

CoolGamer

What is it? Dragons?

Als ik google op xpath namespaces kom ik genoeg tegen wat het probleem beschrijft. Dit is wat ik tegen kwam tussen de resultaten: http://www.edankert.com/defaultnamespaces.html. Het is niet voor de iPhone API, maar ik verwacht dat het redelijk hetzelfde zal werken.

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸


Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 22:44
Thanks, de namespace moest nog gemapped worden inderdaad, de volgende code heeft het dan ook opgelost:

code:
1
2
    NSDictionary *mappings = [NSDictionary dictionaryWithObject:@"http://earth.google.com/kml/2.0" forKey:@"kml"];
    country = [self.xml nodesForXPath:@"//kml:coordinates" namespaceMappings:mappings error:&secondeError];


edit:

Hmm, nu kan ik wel de items selecteren in de buitenste namespace, maar de waardevolle informatie staat in de volgende namespace:
xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"
Hoe kan ik daar via xpath bij komen?

Het nut van namespaces in een xml document ontgaat me ook geheel, welke informatie is er nu in het document wel goed bereikbaar welke zonder deze namespaces niet bereikbaar zou zijn?

[ Voor 40% gewijzigd door ZpAz op 11-08-2009 19:06 ]

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 06-09 16:59

CoolGamer

What is it? Dragons?

Namespaces zijn er om te voorkomen dat er dubbele tags in een document komen met andere betekenissen. De namespace is context waaruit bekeken moet worden wat een tag voorstelt.

Voor die andere namespace zal je, net als de binnenste, een aparte mapping voor moeten maken. Dus die namespace ook opnemen in de Dictionary.

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:02
ZpAz schreef op dinsdag 11 augustus 2009 @ 18:40:
Hmm, nu kan ik wel de items selecteren in de buitenste namespace, maar de waardevolle informatie staat in de volgende namespace:
code:
1
xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"

Hoe kan ik daar via xpath bij komen?
Op dezelfde manier als je eerder deed: introduceer een namespace prefix voor die namespace en gebruik die. (Namespace prefixes in je query hoeven niet overeen te komen met die in het document dat je queriet, zolang ze maar expanden naar hetzelfde paar van namespace en local name, dus het maakt niet uit dat een node in je document toevallig de default namespace gebruikt terwijl je in je query een namespace prefix gebruikt.)

Wellicht kun je ook een default namespace specificeren. (Persoonlijk gebruik ik liever XQuery; dan kun je in de query expliciet namespaces declararen die je nodig hebt.)

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 22:44
Bedankt, dat was de oplossing, wat een hel zeg, een xml bestand parsen @ obj-c voor de iPhone, geen degelijke standaard classe, slechte documentatie van de door de community gemaakte classe... tsja, ik ben iig weer wat verder.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 06-09 16:59

CoolGamer

What is it? Dragons?

De meeste XPath-implementaties werken op deze manier, dus dat is makkelijk als je de volgende keer weer iets maakt om XPath.

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸

Pagina: 1