Parsing XML. Hopp over elementer du ikke trenger

Å analysere XML betyr i hovedsak å krysse et XML-dokument og returnere de riktige dataene. Mens et økende antall nettjenester returnerer data i JSON-format, bruker de fleste fortsatt XML, så det er viktig å mestre XML-parsing hvis du vil bruke hele spekteret av tilgjengelige APIer.

Bruker utvidelsen SimpleXML i PHP, som ble lagt til i PHP 5.0, er det veldig enkelt og greit å jobbe med XML. I denne artikkelen vil jeg vise deg hvordan du gjør dette.

Grunnleggende bruk

La oss starte med følgende eksempel languages.xml:


>

> 1972>
> Dennis ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James gåsling >
>
>

Dette XML-dokumentet inneholder en liste over programmeringsspråk med litt informasjon om hvert språk: året for implementeringen og navnet på dets skaper.

Det første trinnet er å laste XML ved hjelp av funksjoner enten simplexml_load_file () eller simplexml_load_string ()... Som navnet på funksjonene antyder, vil førstnevnte laste XML fra en fil, og sistnevnte vil laste XML fra en streng.

Begge funksjonene leser hele DOM-treet inn i minnet og returnerer et objekt SimpleXMLElement... I eksemplet ovenfor er objektet lagret i $ languages-variabelen. Du kan bruke funksjoner var_dump () eller print_r () for å få detaljer om det returnerte objektet, hvis du vil.

SimpleXMLElement-objekt
[lang] => Array
[0] => SimpleXMLElement-objekt
[@ attributter] => Matrise
[navn] => C
[dukket opp] => 1972
[skaper] => Dennis Ritchie
[1] => SimpleXMLElement-objekt
[@ attributter] => Matrise
[navn] => PHP
[dukket opp] => 1995
[skaper] => Rasmus Lerdorf
[2] => SimpleXMLElement-objekt
[@ attributter] => Matrise
[navn] => Java
[dukket opp] => 1995
[skaper] => James Gosling
)
)

Denne XML-en inneholder rotelementet språk, der det er tre elementer lang. Hvert element i matrisen tilsvarer et element lang i XML-dokumentet.

Du kan få tilgang til egenskapene til et objekt ved å bruke operatoren -> ... For eksempel vil $ languages-> lang returnere et SimpleXMLElement-objekt som samsvarer med det første elementet lang... Dette objektet inneholder to egenskaper: dukket opp og skaperen.

$ languages ​​-> lang [0] -> dukket opp;
$ languages ​​-> lang [0] -> skaper;

Det er veldig enkelt å vise en liste over språk og vise egenskapene deres ved å bruke en standard loop som f.eks for hver.

foreach ($ språk -> lang som $ lang) (
printf (
"" ,
$ lang ["navn"],
$ lang -> dukket opp,
$ lang -> skaper
) ;
}

Legg merke til hvordan jeg fikk tilgang til attributtnavnet til lang-elementet for å få språknavnet. På denne måten kan du få tilgang til alle attributter til et element representert som et SimpleXMLElement-objekt.

Arbeide med navneområder

Når du jobber med XML for ulike nettjenester, vil du støte på elementnavnerom mer enn én gang. La oss endre vår languages.xml for å vise et eksempel på bruk av navneområdet:



xmlns: dc =>

> 1972>
> Dennis ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James gåsling >
>
>

Nå elementet skaperen plassert i navneområdet dc som peker til http://purl.org/dc/elements/1.1/. Hvis du prøver å skrive ut språkskaperne med vår forrige kode, vil det ikke fungere. For å lese navnerommene til elementer, må du bruke en av følgende tilnærminger.

Den første tilnærmingen er å bruke URIer direkte i kode når det refereres til elementets navneområde. Følgende eksempel viser hvordan dette gjøres:

$ dc = $ språk -> lang [1] -> barn ( "http://purl.org/dc/elements/1.1/") ;
echo $ dc -> skaper;

Metode barn () tar et navneområde og returnerer underordnede elementer som starter med et prefiks. Det krever to argumenter, det første er et XML-navneområde og det andre valgfrie argumentet som er standard falsk... Hvis det andre argumentet er TRUE, vil navneområdet bli behandlet som et prefiks. Hvis FALSE, vil navneområdet bli behandlet som et URL-navneområde.

Den andre tilnærmingen er å lese URI-navnene fra dokumentet og bruke dem når du refererer til elementnavneområdet. Dette er faktisk den beste måten å få tilgang til elementene fordi du ikke trenger å hardkode URI.

$ navneområder = $ språk -> getNamespaces (true);
$ dc = $ språk -> lang [1] -> barn ($ navneområder ["dc"]);

echo $ dc -> skaper;

Metode GetNamespaces () returnerer en rekke prefiksnavn og tilhørende URIer. Det krever en ekstra parameter, som som standard er falsk... Hvis du setter det slik ekte så vil denne metoden returnere navnene som brukes i foreldre- og undernodene. Ellers finner den navnerom som bare brukes i den overordnede noden.

Du kan nå gå gjennom listen over språk som følger:

$ languages ​​= simplexml_load_file ("languages.xml");
$ ns = $ språk -> getNamespaces (true);

foreach ($ språk -> lang som $ lang) (
$ dc = $ lang -> barn ($ ns ["dc"]);
printf (
"

% s dukket opp i % d og ble opprettet av % s.

" ,
$ lang ["navn"],
$ lang -> dukket opp,
$ dc -> skaper
) ;
}

Kasusstudie – Parsing av en YouTube-videokanal

La oss ta en titt på et eksempel som mottar en RSS-feed fra en YouTube-kanal og viser lenker til alle videoer fra den. For å gjøre dette, må du kontakte følgende adresse:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL-en returnerer en liste over de nyeste videoene fra den gitte kanalen i XML-format. Vi analyserer XML og får følgende informasjon for hver video:

  • Link til video
  • Miniatyr
  • Navn

Vi starter med å finne og laste inn XML:

$ channel = "Kanalnavn";
$ url = "http://gdata.youtube.com/feeds/api/users/"... $ kanal. "/ laster opp";
$ xml = file_get_contents ($ url);

$ feed = simplexml_load_string ($ xml);
$ ns = $ feed -> getNameSpaces (true);

Hvis du ser på XML-feeden, kan du se at det er flere elementer der inne enhet, som hver lagrer detaljert informasjon om en bestemt video fra en kanal. Men vi bruker bare miniatyrbilder, video-url og tittel. Disse tre elementene er etterkommere av elementet gruppe som igjen er et barn av inngang:

>

>



Tittel... >

>

>

Vi skal bare gå gjennom alle elementene. inngang, og for hver av dem trekker vi ut den nødvendige informasjonen. noter det spiller, miniatyrbilde og tittel er i medienavneområdet. Derfor må vi fortsette som i forrige eksempel. Vi henter navnene fra dokumentet og bruker navneområdet når vi refererer til elementene.

foreach ($ feed -> oppføring som $ entry) (
$ gruppe = $ oppføring -> barn ($ ns ["media"]);
$ gruppe = $ gruppe -> gruppe;
$ thumbnail_attrs = $ gruppe -> thumbnail [1] -> attributter ();
$ image = $ thumbnail_attrs ["url"];
$ spiller = $ gruppe -> spiller -> attributter ();
$ link = $ player ["url"];
$ tittel = $ gruppe -> tittel;
printf ( "

" ,
$ spiller, $ bilde, $ tittel);
}

Konklusjon

Nå som du vet hvordan du bruker SimpleXML For å analysere XML-data kan du forbedre ferdighetene dine ved å analysere forskjellige XML-feeder med forskjellige APIer. Men det er viktig å huske på at SimpleXML leser hele DOM inn i minnet, så hvis du analyserer et stort datasett, kan du gå tom for minne. Les dokumentasjonen for å lære mer om SimpleXML.


Hvis du har spørsmål, anbefaler vi å bruke vår

Nå skal vi studere arbeid med XML. XML er et format for utveksling av data mellom nettsteder. Det er veldig likt HTML, bortsett fra at XML tillater sine egne tagger og attributter.

Hvorfor trenger du XML når du analyserer? Noen ganger har det seg slik at nettstedet du trenger å analysere har et API som du kan få det du vil uten for mye belastning. Derfor bare et tips - før du analyserer nettstedet, sjekk om det har en API.

Hva er en API? Dette er et sett med funksjoner som du kan sende en forespørsel til dette nettstedet med og motta ønsket svar. Dette svaret kommer oftest i XML-format. Så la oss begynne å studere det.

Arbeid med XML i PHP

Anta at du har XML. Det kan være i en streng, eller lagret i en fil, eller returnert på forespørsel til en bestemt URL.

La XML-en lagres i en streng. I dette tilfellet, fra denne linjen må du lage et objekt ved hjelp av nytt SimpleXMLElement:

$ str = " Kolya 25 1000 "; $ xml = nytt SimpleXMLElement ($ str);

Nå har vi en variabel $ xml et objekt med analysert XML lagres. Ved å få tilgang til egenskapene til dette objektet kan du få tilgang til innholdet i XML-taggene. Hvordan nøyaktig - vi vil analysere litt nedenfor.

Hvis XML er lagret i en fil eller returneres ved tilgang til en URL (som oftest er tilfellet), bør du bruke funksjonen simplexml_load_file som gjør det samme objektet $ xml:

Kolya 25 1000

$ xml = simplexml_load_file (bane til fil eller url);

Hvordan arbeide

I eksemplene nedenfor er vår XML lagret i en fil eller URL.

La følgende XML gis:

Kolya 25 1000

La oss få navn, alder og lønn til den ansatte:

$ xml = simplexml_load_file (bane til fil eller url); echo $ xml-> navn; // skriver ut "Kolya" echo $ xml-> age; // skriver ut 25 echo $ xml-> lønn; // vil skrive ut 1000

Som du kan se, har $ xml-objektet egenskaper som tilsvarer kodene.

Du har kanskje lagt merke til at taggen vises ikke noe sted i adressen. Dette er fordi det er root-taggen. Du kan endre navn på den, for eksempel til - og ingenting vil endre seg:

Kolya 25 1000

$ xml = simplexml_load_file (bane til fil eller url); echo $ xml-> navn; // skriver ut "Kolya" echo $ xml-> age; // skriver ut 25 echo $ xml-> lønn; // vil skrive ut 1000

Det kan bare være én root-tag i XML, akkurat som en tag i vanlig HTML.

La oss endre XML-en litt:

Kolya 25 1000

I dette tilfellet vil vi få en kjede av samtaler:

$ xml = simplexml_load_file (bane til fil eller url); echo $ xml-> arbeider-> navn; // skriver ut "Kolya" echo $ xml-> arbeider-> alder; // skriver ut 25 echo $ xml-> arbeider-> lønn; // vil skrive ut 1000

Arbeid med attributter

La noen data lagres i attributter:

Nummer 1

$ xml = simplexml_load_file (bane til fil eller url); echo $ xml-> arbeider ["navn"]; // viser "Kolya" echo $ xml-> arbeider ["alder"]; // skriver ut 25 echo $ xml-> arbeider ["lønn"]; // skriver ut 1000 echo $ xml-> arbeider; // viser "Nummer 1"

Orddelingskoder

Tagger (og attributter) med bindestrek er tillatt i XML. I dette tilfellet får man tilgang til slike tagger slik:

Kolya Ivanov

$ xml = simplexml_load_file (bane til fil eller url); echo $ xml-> arbeider -> (fornavn); // skriver ut "Kolya" echo $ xml-> arbeider -> (etternavn); // viser "Ivanov"

Iterasjon over en loop

La oss nå ikke ha én ansatt, men flere. I dette tilfellet kan vi iterere over objektet vårt ved å bruke en foreach loop:

Kolya 25 1000 Vasya 26 2000 Peter 27 3000

$ xml = simplexml_load_file (bane til fil eller url); foreach ($ xml som $ arbeider) (ekko $ arbeider-> navn; // skriver ut "Kolya", "Vasya", "Petya")

Fra objekt til normal array

Hvis du ikke er komfortabel med å jobbe med et objekt, kan du konvertere det til en vanlig PHP-array ved å bruke følgende smarte triks:

$ xml = simplexml_load_file (bane til fil eller url); var_dump (json_decode (json_encode ($ xml), true));

Mer informasjon

Parsing basert på sitemap.xml

Ofte har nettstedet en sitemap.xml-fil. Denne filen lagrer lenker til alle sidene på nettstedet for å gjøre det enklere å indeksere dem av søkemotorer (indeksering er faktisk parsing av nettstedet av Yandex og Google).

Generelt bør vi ikke bry oss mye om hvorfor denne filen er nødvendig, det viktigste er at hvis den eksisterer, kan du ikke klatre på sidene på nettstedet ved å bruke noen smarte metoder, men bare bruke denne filen.

Slik sjekker du tilstedeværelsen av denne filen: la oss analysere site.ru-nettstedet, og gå deretter til site.ru/sitemap.xml i nettleseren - hvis du ser noe, er det der, og hvis du ikke ser det , så dessverre.

Hvis det er et nettstedskart, inneholder det lenker til alle sidene på nettstedet i XML-format. Ta denne XML-en rolig, parse den, separate lenker til sidene du trenger på noen måte som er praktisk for deg (for eksempel ved å analysere URL-en, som ble beskrevet i edderkoppmetoden).

Som et resultat får du en liste over lenker for parsing, du trenger bare å gå til dem og analysere innholdet du trenger.

Les mer om sitemap.xml-enheten i Wikipedia.

Hva du skal gjøre videre:

Begynn å løse problemer på følgende lenke: oppgaver til leksjonen.

Når du har bestemt deg for alt, gå videre til å studere et nytt emne.


publisering av denne artikkelen er kun tillatt med en lenke til nettstedet til forfatteren av artikkelen

I denne artikkelen vil jeg vise deg et eksempel på hvordan du analyserer en stor XML-fil. Hvis serveren din (hosting) ikke forbyr en økning i kjøretiden til skriptet, kan du analysere en XML-fil som veier minst gigabyte, han parset personlig kun filer fra ozon som veier 450 megabyte.

Det er to problemer når du analyserer store XML-filer:
1. Ikke nok minne.
2. Det er ikke tildelt nok tid til at manuset skal fungere.

Det andre problemet med tid kan løses hvis serveren ikke forbyr det.
Men problemet med minne er vanskelig å løse, selv om vi snakker om din egen server, så er det ikke veldig enkelt å flytte filer på 500 megabyte, og det er rett og slett umulig å øke minnet på hosting og på VDS.

PHP har flere innebygde XML-behandlingsalternativer - SimpleXML, DOM, SAX.
Alle disse alternativene er beskrevet i mange eksempelartikler, men alle eksemplene viser arbeid med et komplett XML-dokument.

Her er ett eksempel, å hente et objekt fra en XML-fil

Nå kan du behandle dette objektet, MEN ...
Som du kan se, leses hele XML-filen inn i minnet, deretter blir alt analysert til et objekt.
Det vil si at alle data går inn i minnet, og hvis det tildelte minnet er lite, stopper skriptet.

Dette alternativet er ikke egnet for behandling av store filer, du må lese filen linje for linje og behandle disse dataene etter tur.
I dette tilfellet utføres validitetskontrollen på samme måte som dataene behandles, så du må kunne tilbakestille, for eksempel slette alle dataene som er lagt inn i databasen ved ugyldig XML-fil, eller foreta to passeringer gjennom filen, les først for gyldighet, les deretter for behandling av data.

Her er et teoretisk eksempel på å analysere en stor XML-fil.
Dette skriptet leser ett tegn om gangen fra filen, samler disse dataene i blokker og sender dem til XML-parseren.
Denne tilnærmingen løser minneproblemet fullstendig og forårsaker ikke stress, men forverrer problemet over tid. Hvordan prøve å løse problemet over tid, les nedenfor.

Funksjon webi_xml ($ fil)
{

########
### funksjon for arbeid med data

{
print $ data;
}
############################################



{
print $ navn;
print_r ($ attrs);
}


## slutttag-funksjon
funksjon endElement ($ parser, $ navn)
{
print $ navn;
}
############################################

($ xml_parser, "data");

// åpne filen
$ fp = fopen ($ fil, "r");

$ perviy_vxod = 1; $ data = "";



{

$ simvol = fgetc ($ fp); $ data. = $ simvol;


if ($ simvol! = ">") (fortsett;)


ekko "

gå i stykker;
}

$ data = "";
}
fclose ($ fp);

Webi_xml ("1.xml");

?>

I dette eksemplet legger jeg alt i én funksjon webi_xml () og helt nederst kan du se kallet.
Selve skriptet består av tre hovedfunksjoner:
1. Funksjonen som fanger åpningen av startElement ()-taggen
2. En funksjon som fanger opp endElement ()-taggen som lukkes
3. Og funksjonen for å motta datadata ().

Anta at innholdet i filen 1.xml er en oppskrift



< title >Enkelt brød
< ingredient amount = "3" unit = "стакан" >Mel
< ingredient amount = "0.25" unit = "грамм" >Gjær
< ingredient amount = "1.5" unit = "стакан" >Varmt vann
< ingredient amount = "1" unit = "чайная ложка" >Salt
< instructions >
< step > Bland alle ingrediensene og elt grundig.
< step > Dekk til med et klede og la stå i en time i et varmt rom..
< step > Elt igjen, legg på en bakeplate og sett i ovnen.
< step > Besøk nettstedet


Vi starter med å kalle fellesfunksjonen webi_xml ("1.xml");
Videre i denne funksjonen starter parseren og alle taggnavn konverteres til store bokstaver slik at alle tagger har samme store og små bokstaver.

$ xml_parser = xml_parser_create ();
xml_parser_set_option ($ xml_parser, XML_OPTION_CASE_FOLDING, true);

Nå indikerer vi hvilke funksjoner som vil fungere for å fange åpningen av taggen, lukke og behandle dataene

xml_set_element_handler ($ xml_parser, "startElement", "endElement");
xml_set_character_data_handler($ xml_parser, "data");

Deretter kommer åpningen av den spesifiserte filen, iterering over filen ett tegn om gangen, og hvert tegn legges til strengvariabelen til tegnet er funnet > .
Hvis dette er den aller første tilgangen til filen, så slettes underveis alt som vil være overflødig i begynnelsen av filen, alt som er før , dette er taggen som XML skal starte med.
For første gang vil strengvariabelen samle strengen

Og send henne til parseren
xml_parse ($ xml_parser, $ data, feof ($ fp));
Etter å ha behandlet dataene, blir strengvariabelen forkastet og datainnsamlingen i strengen starter på nytt og strengen dannes en gang til

I den tredje
</b><br>på den fjerde <br><b>Enkelt brød

Vær oppmerksom på at strengvariabelen alltid dannes av den ferdige taggen > og det er ikke nødvendig å sende en åpen og lukket tag med data til edderkoppen for eksempel
Enkelt brød
Det er viktig for denne behandleren å få en hel ikke ødelagt tagg, minst en åpen tag, men i neste trinn en lukket tagg, eller umiddelbart få 1000 linjer av filen, det spiller ingen rolle, det viktigste er at taggen går ikke i stykker, for eksempel

le> Enkelt brød
Du kan ikke sende data til behandleren på denne måten, fordi taggen er ødelagt.
Du kan komme opp med din egen metode for å sende data til behandleren, for eksempel samle 1 megabyte med data og sende det til behandleren for å øke hastigheten, bare sørg for at taggene alltid er fullført og dataene kan brytes
Enkel</b><br><b>brød

Dermed kan du, i deler som du ønsker, sende en stor fil til behandleren.

La oss nå se på hvordan disse dataene behandles og hvordan du får dem.

La oss starte med åpningstagger-funksjonen startElement ($ parser, $ navn, $ attrs)
Anta at behandlingen har nådd linjen
< ingredient amount = "3" unit = "стакан" >Mel
Deretter, inne i funksjonen, vil variabelen $ navn være lik ingrediens det vil si navnet på den åpne taggen (den har ikke kommet til å lukke taggen ennå).
I dette tilfellet vil også en rekke attributter for denne $ attrs-taggen være tilgjengelig, der det vil være data beløp = "3" og enhet = "glass".

Etter det, behandlingen av dataene til den åpne taggen med funksjonen data ($ parser, $ data)
$ datavariabelen vil inneholde alt mellom åpnings- og avslutningstaggen, i vårt tilfelle er dette teksten Flour

Og behandlingen av strengen vår fullføres av funksjonen endElement ($ parser, $ navn)
Dette er navnet på den lukkede taggen, i vårt tilfelle vil $ navn være lik ingrediens

Og etter det gikk alt i ring igjen.

Eksempelet ovenfor viser bare prinsippet for XML-behandling, men for reell bruk må det forbedres.
Vanligvis er det nødvendig å parse stor XML for å legge inn data i databasen, og for korrekt databehandling må du vite hvilken åpen tag dataene tilhører, hvilket tag nestet nivå og hvilke tagger som er åpne i hierarkiet høyere. Med denne informasjonen kan du behandle filen riktig uten problemer.
For å gjøre dette må du legge inn flere globale variabler som samler informasjon om åpne tagger, nesting og data.
Her er et eksempel du kan bruke

Funksjon webi_xml ($ fil)
{
global $ webi_depth; // teller for å spore hekkedybden
$ webi_depth = 0;
global $ webi_tag_open; // vil inneholde en rekke åpne tagger
$ webi_tag_open = array ();
global $ webi_data_temp; // denne matrisen vil inneholde dataene til én tag

####################################################
### funksjon for arbeid med data
funksjonsdata ($ parser, $ data)
{
global $ webi_depth;
global $ webi_tag_open;
global $ webi_data_temp;
// legg til data til matrisen som indikerer neste og åpne tag
$ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["data"]. = $ data;
}
############################################

####################################################
### åpningstaggerfunksjon
funksjon startElement ($ parser, $ navn, $ attrs)
{
global $ webi_depth;
global $ webi_tag_open;
global $ webi_data_temp;

// hvis nesting-nivået ikke lenger er null, er én tag allerede åpen
// og dataene fra den allerede er i arrayet, kan du behandle den
if ($ webi_depth)
{




" ;

skrive ut "
" ;
print_r ($ webi_tag_open); // rekke åpne tagger
skrive ut "


" ;

// etter å ha behandlet dataene, slett dem for å frigjøre minne
unset ($ GLOBALS ["webi_data_temp"] [$ webi_depth]);
}

// nå har åpningen av neste tag startet og videre behandling vil finne sted ved neste trinn
$ webi_depth ++; // øke hekkingen

$ webi_tag_open [$ webi_depth] = $ navn; // legg til den åpne taggen til informasjonsarrayen
$ webi_data_temp [$ webi_depth] [$ navn] ["attrs"] = $ attrs; // legg nå til tag-attributtene

}
###############################################

#################################################
## slutttag-funksjon
funksjon endElement ($ parser, $ navn) (
global $ webi_depth;
global $ webi_tag_open;
global $ webi_data_temp;

// det er her databehandling starter, for eksempel å legge til databasen, lagre til en fil, etc.
// $ webi_tag_open inneholder en kjede med åpne tagger etter neste nivå
// for eksempel $ webi_tag_open [$ webi_depth] inneholder navnet på den åpne taggen hvis informasjon for øyeblikket behandles
// $ webi_depth tag neste nivå
// $ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["attrs"] rekke tag-attributter
// $ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["data"] tagdata

Skriv ut "data". $ webi_tag_open [$ webi_depth]. "-". ($ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["data"]). "
" ;
print_r ($ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["attrs"]);
skrive ut "
" ;
print_r ($ webi_tag_open);
skrive ut "


" ;

Unset ($ GLOBALS ["webi_data_temp"]); // etter å ha behandlet dataene, slett hele arrayet med data, siden taggen ble lukket
unset ($ GLOBALS ["webi_tag_open"] [$ webi_depth]); // fjern informasjon om denne åpne taggen ... siden den ble lukket

$ webi_depth -; // redusere hekking
}
############################################

$ xml_parser = xml_parser_create ();
xml_parser_set_option ($ xml_parser, XML_OPTION_CASE_FOLDING, true);

// spesifiser hvilke funksjoner som vil fungere når du åpner og lukker tagger
xml_set_element_handler ($ xml_parser, "startElement", "endElement");

// spesifiser en funksjon for arbeid med data
xml_set_character_data_handler($ xml_parser, "data");

// åpne filen
$ fp = fopen ($ fil, "r");

$ perviy_vxod = 1; // flagg for å sjekke den første filoppføringen
$ data = ""; // her samler vi inn data fra filen i deler og sender den til xml-parseren

// loop til slutten av filen er funnet
mens (! feof ($ fp) og $ fp)
{
$ simvol = fgetc ($ fp); // les ett tegn fra filen
$ data. = $ simvol; // legg til dette symbolet i dataene som skal sendes

// hvis tegnet ikke er en sluttkode, går vi tilbake til begynnelsen av løkken og legger til ett tegn til i dataene, og så videre til sluttkoden blir funnet
if ($ simvol! = ">") (fortsett;)
// hvis en avsluttende tag ble funnet, send nå disse innsamlede dataene for behandling

// sjekk om dette er den første oppføringen i filen, og slett alt som er før taggen// siden noen ganger kan søppel bli funnet før begynnelsen av XML (klossete redaktører, eller filen mottas av et skript fra en annen server)
if ($ perviy_vxod) ($ data = strstr ($ data, "

// nå kaster vi dataene inn i xml-parseren
if (! xml_parse ($ xml_parser, $ data, feof ($ fp))) (

// her kan du behandle og få feil for gyldighet ...
// så snart en feil oppstår, stopper parsingen
ekko "
XML-feil: ". Xml_error_string (xml_get_error_code ($ xml_parser));
ekko "på linje". xml_get_current_line_number ($ xml_parser);
gå i stykker;
}

// etter parsing, forkast de innsamlede dataene for neste trinn i syklusen.
$ data = "";
}
fclose ($ fp);
xml_parser_free ($ xml_parser);
// fjern globale variabler
unset ($ GLOBALS ["webi_depth"]);
unset ($ GLOBALS ["webi_tag_open"]);
unset ($ GLOBALS ["webi_data_temp"]);

Webi_xml ("1.xml");

?>

Hele eksemplet ble ledsaget av kommentarer, nå test og eksperimenter.
Vær oppmerksom på at i funksjonen til å jobbe med data, blir data ikke bare satt inn i en matrise, men lagt til ved å bruke " .=" siden dataene kanskje ikke kommer i sin helhet og hvis du lager en enkel oppgave, vil du fra tid til annen motta data i biter.

Vel, det er alt, nå er det nok minne når du behandler en fil uansett størrelse, men skriptets kjøretid kan økes på flere måter.
Sett inn funksjonen i begynnelsen av skriptet
set_time_limit (6000);
eller
ini_set ("maks_utførelsestid", "6000");

Eller legg til teksten i .htaccess-filen
php_value max_execution_time 6000

Disse eksemplene vil øke kjøretiden til skriptet til 6000 sekunder.
Du kan øke tiden på denne måten bare i deaktivert modus.

Hvis du har tilgang til edit php.ini kan du øke tiden med
max_execution_time = 6000

For eksempel, på hosting masterhost, når dette skrives, er det forbudt å øke skripttiden, til tross for deaktivert sikker modus, men hvis du er en proff, kan du lage din egen php-assembly på masterhosten, men dette er ikke om det i denne artikkelen.

Noen av eksemplene i denne opplæringen inkluderer en XML-streng. I stedet for å gjenta det i hvert eksempel, legg den linjen i en fil, som du inkluderer i hvert eksempel. Denne linjen er vist i følgende eksempel. I tillegg kan du lage et XML-dokument og lese det med funksjonen simplexml_load_file ().

Eksempel # 1 Eksempel.php-fil med XML-streng

$ xmlstr =<<


PHP: Vi introduserer Parser


Ms. Koder
Onlivia Actora


MR. Koder
El ActÓr


Så det er et språk. Det er fortsatt et programmeringsspråk. Eller
er det et skriptspråk? Alt avsløres i denne dokumentaren
som en skrekkfilm.




7
5


XML;
?>

SimpleXML er enkel å bruke! Prøv å hente en streng eller et nummer fra det underliggende XML-dokumentet.

Eksempel # 2 Henter en del av et dokument

inkludere "example.php";

echo $ filmer -> film [0] -> plot;
?>

Så det er et språk. Det er fortsatt et programmeringsspråk. Eller er det et skriptspråk? Alt avsløres i denne skrekklignende dokumentaren.

I PHP kan du få tilgang til et element i et XML-dokument som inneholder ugyldige tegn (som en bindestrek) i navnet ved å omslutte det gitte elementnavnet i krøllete klammeparenteser og apostrof.

Eksempel # 3 Hente en streng

inkludere "example.php";

echo $ movies -> movie -> ("great-lines") -> line;
?>

Resultatet av dette eksemplet:

PHP løser alle mine nettproblemer

Eksempel # 4 Tilgang til ikke-unike elementer i SimpleXML

I tilfelle det er flere forekomster av underordnede elementer i ett overordnet element, må du bruke standard iterasjonsmetoder.

inkludere "example.php";

$ filmer = nytt SimpleXMLElement ($ xmlstr);

/ * For hver node , vil vi vise navnet separat . */
foreach ($ filmer -> film -> karakterer -> karakter som $ karakter) (
echo $ karakter -> navn, "spiller", $ karakter -> skuespiller, PHP_EOL;
}

?>

Resultatet av dette eksemplet:

Ms. Coder spilt av Onlivia Actora Mr. Coder spilt av El ActÓr

Kommentar:

Egenskaper ( $ filmer-> film i forrige eksempel) er ikke matriser. Det er en iterabel som en array.

Eksempel # 5 Bruke attributter

Til nå har vi bare fått navn og verdier på elementene. SimpleXML kan også få tilgang til attributtene til et element. Et elementattributt kan nås på samme måte som matriseelementer ( array).

inkludere "example.php";

$ filmer = nytt SimpleXMLElement ($ xmlstr);

/ * Tilgang til noden den første filmen.
* Vi vil også vise vurderingsskalaen. * /
foreach ($ filmer -> film [0] -> vurdering som $ vurdering) (
bryter ((streng) $ vurdering ["type"]) ( // Få attributtene til elementet etter indeks
case "thumbs":
ekko $ vurdering, "tommel opp";
gå i stykker;
sak "stjerner":
echo $ vurdering, "stjerner";
gå i stykker;
}
}
?>

Resultatet av dette eksemplet:

7 tommel opp5 stjerner

Eksempel # 6 Sammenligning av elementer og attributter med tekst

For å sammenligne et element eller attributt med en streng, eller sende det til en funksjon som tekst, må du caste det til en streng ved å bruke (streng)... Ellers vil PHP behandle elementet som et objekt.

inkludere "example.php";

$ filmer = nytt SimpleXMLElement ($ xmlstr);

if ((streng) $ filmer -> film -> tittel == "PHP: The Rise of the Parser") {
skrive ut "Min favorittfilm.";
}

echo htmlentities ((streng) $ filmer -> film -> tittel);
?>

Resultatet av dette eksemplet:

Min favorittfilm Php: The Emergence of the Parser

Eksempel # 7 Sammenligning av to elementer

To SimpleXMLElements anses som forskjellige selv om de peker til det samme objektet siden PHP 5.2.0.

inkludere "example.php";

$ movies1 = nytt SimpleXMLElement ($ xmlstr);
$ movies2 = nytt SimpleXMLElement ($ xmlstr);
var_dump ($ filmer1 == $ filmer2); // usann siden PHP 5.2.0
?>

Resultatet av dette eksemplet:

Eksempel # 8 Bruke XPath

SimpleXML inkluderer innebygd XPath-støtte. Finn alle gjenstander :

inkludere "example.php";

$ filmer = nytt SimpleXMLElement ($ xmlstr);

foreach ($ filmer -> xpath ("// karakter") som $ karakter) (
echo $ karakter -> navn, "spiller", $ karakter -> skuespiller, PHP_EOL;
}
?>

"// "fungerer som en mal. For å spesifisere en absolutt bane, utelate en av skråstrekene.

Resultatet av dette eksemplet:

Ms. Coder spilt av Onlivia Actora Mr. Coder spilt av El ActÓr

Eksempel # 9 Innstillingsverdier

Data i SimpleXML trenger ikke å være uforanderlig. Objektet lar deg manipulere alle elementer.

inkludere "example.php";
$ filmer = nytt SimpleXMLElement ($ xmlstr);

$ filmer -> film [0] -> tegn -> karakter [0] -> navn = "Frøken Koder";

echo $ filmer -> asXML ();
?>

Resultatet av dette eksemplet:

PHP: Vi introduserer Parser Frøken koder Onlivia Actora MR. Koder El ActÓr 7 5

Eksempel # 10 Legge til elementer og attributter

Siden PHP 5.1.3 har SimpleXML muligheten til å enkelt legge til underordnede elementer og attributter.

inkludere "example.php";
$ filmer = nytt SimpleXMLElement ($ xmlstr);

$ karakter = $ filmer -> film [0] -> tegn -> addChild ("karakter");
$ karakter -> addChild ("navn", "Mr. Parser");
$ karakter -> addChild ("skuespiller", "John Doe");

$ vurdering = $ filmer -> film [0] -> addChild ("vurdering", "PG");
$ rating -> addAttribute ("type", "mpaa");

echo $ filmer -> asXML ();
?>

Resultatet av dette eksemplet:

PHP: Vi introduserer Parser Ms. Koder Onlivia Actora MR. Koder El ActÓr MR. ParserJohn Doe Så det er et språk. Det er fortsatt et programmeringsspråk. Eller er det et skriptspråk? Alt avsløres i denne skrekklignende dokumentaren. PHP løser alle mine weboppgaver 7 5 PG

Eksempel # 11 Interaksjon med DOM

PHP kan konvertere XML-noder fra SimpleXML til DOM-format og omvendt. Dette eksemplet viser hvordan du kan endre et DOM-element i SimpleXML.

$ dom = nytt DOMDocument;
$ dom -> loadXML ( "tull" );
hvis (! $ dom) (
ekko "Det oppstod en feil under parsing av dokumentet";
exit;
}

$ bøker = simplexml_import_dom ($ dom);

echo $ bøker -> bok [0] -> tittel;
?>

Resultatet av dette eksemplet:

4 år siden

Det er et vanlig "triks" som ofte foreslås for å konvertere et SimpleXML-objekt til en matrise, ved å kjøre det gjennom json_encode () og deretter json_decode (). Jeg vil gjerne forklare hvorfor dette er en dårlig idé.

Enkelt sagt fordi hele poenget med SimpleXML er å være enklere å bruke og kraftigere enn en vanlig array. Du kan for eksempel skrivebar -> baz ["bing"]?> og det betyr det samme sombar [0] -> baz [0] ["bing"]?>, uavhengig av hvor mange bar eller baz-elementer det er i XML; og hvis du skriverbar [0] -> baz [0]?> får du alt strenginnholdet til den noden - inkludert CDATA-seksjoner - uavhengig av om den også har underordnede elementer eller attributter. Du har også tilgang til navneromsinformasjon, muligheten til å gjøre enkle redigeringer av XML, og til og med muligheten til å "importere" til et DOM-objekt, for mye kraftigere manipulasjon. Alt dette går tapt ved å gjøre objektet om til en array i stedet for å lese og forstå eksemplene på denne siden.

I tillegg, fordi den ikke er designet for dette formålet, vil konverteringen til JSON og tilbake faktisk miste informasjon i enkelte situasjoner. For eksempel vil alle elementer eller attributter i et navneområde ganske enkelt bli forkastet, og alt tekstinnhold vil bli forkastet hvis et element også har underordnede eller attributter. Noen ganger spiller dette ingen rolle, men hvis du har for vane å konvertere alt til arrays, kommer det til å svi deg til slutt.

Selvfølgelig kan du skrive en smartere konvertering, som "ikke hadde disse begrensningene, men på det tidspunktet får du ingen verdi ut av SimpleXML i det hele tatt, og bør bare bruke XML Parser-funksjonene på lavere nivå, eller XMLReader-klassen, for å lage din struktur. Du vil fortsatt "ikke ha den ekstra bekvemmelighetsfunksjonen til SimpleXML, men det" er ditt tap.

2 år siden

Hvis xml-strengen din inneholder booleaner kodet med "0" og "1", vil du få problemer når du caster elementet direkte til bool:

$ xmlstr =<<

1
0

XML;
$ verdier = nytt SimpleXMLElement ($ xmlstr);
$ truevalue = (bool) $ values-> truevalue; // sant
$ falsevalue = (bool) $ values-> falsevalue; // også sant!!!

I stedet må du kaste til streng eller int først:

$ truevalue = (bool) (int) $ values-> truevalue; // sant
$ falsevalue = (bool) (int) $ values-> falsevalue; // falsk

9 år siden

Hvis du trenger å skrive ut gyldig xml i svaret ditt, ikke glem å sette overskriftens innholdstype til xml i tillegg til å gjengi resultatet av asXML ():

$ xml = simplexml_load_file ("...");
...
... xml-ting
...

// output xml i svaret ditt:
header ("Innholdstype: tekst / xml");
echo $ xml -> asXML ();
?>

9 år siden

Fra README-filen:

SimpleXML er ment å være en enkel måte å få tilgang til XML-data.

SimpleXML-objekter følger fire grunnleggende regler:

1) egenskaper angir element-iteratorer
2) numeriske indekser angir elementer
3) ikke-numeriske indekser angir attributter
4) strengkonvertering lar deg få tilgang til TEKST-data

Når du itererer egenskaper, itererer utvidelsen alltid over
alle noder med det elementnavnet. Slik metode barn () må være
kalt til å iterere over subnoder. Men gjør også følgende:
foreach ($ obj-> node_name som $ elem) (
// gjør noe med $ elem
}
resulterer alltid i iterasjon av "node_name"-elementer. Så ikke lenger
sjekk er nødvendig for å skille antall noder av den typen.

Når et element får tilgang til TEXT-data via en egenskap
da inkluderer ikke resultatet TEXT-dataene til underelementene.

Kjente problemer
============

På grunn av motorproblemer er det foreløpig ikke mulig å få tilgang
et underelement ved indeks 0: $ objekt-> egenskap.

8 år siden

Å bruke ting som: is_object ($ xml-> modul-> admin) for å sjekke om det faktisk er en node kalt "admin", ser ikke ut til å fungere som forventet, siden simplexml alltid returnerer et objekt - i så fall en tom en - selv om en bestemt node ikke eksisterer.
For meg ser den gode gamle tomme () funksjonen ut til å fungere helt fint i slike tilfeller.

8 år siden

Et raskt tips om xpath-spørringer og standard navneområder. Det ser ut som XML-systemet bak SimpleXML fungerer på samme måte som jeg tror XML-systemet .NET bruker: når man trenger å adressere noe i standardnavneområdet, må man deklarere navneområdet ved å bruke registerXPathNamespace og deretter bruke prefikset til adresse ellers i standard navneområde levende element.

$ streng =<<

Førti Hva?
Joe
Jane

Jeg vet at "svaret er - men hva" er spørsmålet?




XML;

$ xml = simplexml_load_string ($-streng);
$ xml -> registerXPathNamespace ("def", "http://www.w3.org/2005/Atom");

$ noder = $ xml -> xpath ("// def: document / def: title");

?>

9 år siden

Mens SimpleXMLElement hevder å kunne itereres, ser det ikke ut til at det implementerer standard Iterator-grensesnittfunksjoner som :: neste og :: tilbakestilles på riktig måte. Mens foreach () fungerer, ser det ikke ut til at funksjoner som neste (), gjeldende () eller hver () fungerer som du forventer - pekeren ser aldri ut til å bevege seg eller blir stadig tilbakestilt.

6 år siden

Hvis kodingen av XML-dokumentet er forskjellig fra UTF-8, må kodingserklæringen følge umiddelbart etter versjon = "..." og før frittstående = "...". Dette er et krav i XML-standarden.

Hvis koding av XML-dokument er forskjellig fra UTF-8. Kodingserklæringen bør følge umiddelbart etter versjonen = "..." og før frittstående = "...". Dette kravet er standard XML.


Ok

Russisk språk. russisk språk


Fatal feil: Uoppdaget unntak "Unntak" med meldingen "Strengen kunne ikke analyseres som XML" i ...

Extensible Markup Language XML er et sett med regler for koding av dokumenter i maskinlesbar form. XML er et populært format for utveksling av data på Internett. Nettsteder som ofte oppdaterer innholdet, for eksempel nyhetssider eller blogger, tilbyr ofte en XML-feed for å holde eksterne programmer oppmerksomme på innholdsendringer. Sende og analysere XML-data er en vanlig oppgave for nettverksapplikasjoner. Denne leksjonen forklarer hvordan du analyserer XML-dokumenter og bruker dataene deres.

Velge en parser

Kanalanalyse

Det første trinnet i å analysere en feed er å bestemme hvilke datafelt du er interessert i. Parseren trekker ut de angitte feltene og ignorerer alt annet.

Her er en feedkodebit som vil bli utforsket i eksempelapplikasjonen. Hvert innlegg på StackOverflow.com vises i feeden som en oppføringskode som inneholder flere nestede tagger:

nyeste spørsmål tagget android - Stack Overflow ... ... http://stackoverflow.com/q/9439999 0 Hvor er datafilen min? cliff2310 http://stackoverflow.com/users/1128925 2012-02-25T00: 30: 54Z 2012-02-25T00: 30: 54Z

Jeg har et program som krever en datafil ...

... ...

Eksempelappen trekker ut data fra oppføringstaggen og dens undertagger tittel, lenke og sammendrag.

Instantiering av parseren

Det neste trinnet er å instansiere parseren og starte parsingsprosessen. Denne kodebiten initialiserer parseren slik at den ikke håndterer navneområder og bruker den oppgitte InputStream som input. Parseprosessen startes ved å kalle nextTag () og kaller opp readFeed ()-metoden, som henter og behandler dataene applikasjonen er interessert i:

Offentlig klasse StackOverflowXmlParser (// Vi bruker ikke navnerom private static final String ns = null; public List parse (InputStream in) kaster XmlPullPullParserException, IOException (try (XmlPullParser parser = Xml.newPullParser (); parsull_arserset.Xml. ); parser.setInput (in, null); parser.nextTag (); returner readFeed (parser);) til slutt (in.close ();)) ...)

Trekk fra kanal

ReadFeed ()-metoden gjør selve arbeidet med å håndtere feeden. Elementer merket med «entry»-taggen er utgangspunktet for rekursiv kanalbehandling. Hvis den neste etiketten ikke er en inngangsetikett, hoppes den over. Etter at hele feeden har blitt rekursivt behandlet, returnerer readFeed () en liste som inneholder oppføringene (inkludert nestede dataelementer) som er hentet fra feeden. Denne listen returneres deretter av parseren.

Private List readFeed (XmlPullParser parser) kaster XmlPullParserException, IOException (List entries = new ArrayList (); parser.require (XmlPullParser.START_TAG, ns, "feed"); while (parser.next ()! = XmlPullPull.Pull. getEventType ()! = XmlPullParser.START_TAG) (fortsett;) Strengnavn = parser.getName (); // Starter med å se etter oppføringskoden if (name.equals ("entry")) (entries.add ( readEntry (parser) ));) else (hopp over (parser);)) returner oppføringer;)

Parsing XML

Trinnene for å analysere en XML-feed er som følger:

Dette utdraget viser hvordan parseren analyserer oppføring, tittel, kobling og sammendrag.

Offentlig statisk klasseoppføring (offentlig endelig strengtittel; offentlig endelig strenglenke; offentlig endelig strengsammendrag; privat oppføring (strengtittel, strengsammendrag, strenglenke) (this.title = tittel; this.summary = sammendrag; this.link = lenke ;)) // Analyserer innholdet i en oppføring. Hvis den støter på en tittel, et sammendrag eller en lenkekode, overlater du dem // til deres respektive "lese"-metoder for behandling. Ellers hopper du over taggen. private Entry readEntry (XmlPullParser parser) kaster XmlPullParserException, IOException (parser.require (XmlPullParser.START_TAG, ns, "entry"); String title = null; String summary = null; String link = null.next (parser!) = XmlPullParser.END_TAG) (if (parser.getEventType ()! = XmlPullParser.START_TAG) (fortsett;) String name = parser.getName (); if (name.equals ("title")) (title = readTitle (parser) ;) else if (name.equals ("sammendrag")) (summary = readSummary (parser);) else if (name.equals ("link")) (link = readLink (parser);) else (hopp over (parser) ;)) returner ny oppføring (tittel, sammendrag, lenke);) // Behandler tittelkoder i feeden. private String readTitle (XmlPullParser parser) kaster IOException, XmlPullParserException (parser.require (XmlPullParser.START_TAG, ns, "title"); String title = readText (parser); parser.require (XmlPullParser"); return.END "title"; ) // Behandler lenketagger i feeden. private String readLink (XmlPullParser parser) kaster IOException, XmlPullParserException (String link = ""; parser.require (XmlPullParser.START_TAG, ns, "link"); String tag = parser.getName (); String triburelType = parser.getueA (tnullteValueA) , "rel"); if (tag.equals ("link")) (if (relType.equals ("alternate")) (link = parser.getAttributeValue (null, "href"); parser.nextTag ();) ) parser.require (XmlPullParser.END_TAG, ns, "link"); return link;) // Behandler sammendragstagger i feeden. private String readSummary (XmlPullParser-parser) kaster IOException, XmlPullParserException (parser.require (XmlPullParser.START_TAG, ns, "summary"); String summary = readText (parser); parser.require (XmlPullParser summary; "return_TAG summary"); ) // For taggenes tittel og sammendrag, trekker ut tekstverdiene deres. private String readText (XmlPullParser parser) kaster IOException, XmlPullParserException (String result = ""; if (parser.next () == XmlPullParser.TEXT) (result = parser.getText (); parser.nextTag ();) return result; ) ...)

Hopp over elementer du ikke trenger

I et av XML-parsingstrinnene beskrevet ovenfor, hopper parseren over tagger som vi ikke er interessert i. Nedenfor er koden til skip ()-metodeparseren:

Privat void-hopp (XmlPullParser-parser) kaster XmlPullParserException, IOException (if (parser.getEventType ()! = XmlPullParser.START_TAG) (kast ny IllegalStateException ();) int dybde = 1; while (depth! = (0) neste ()) (case XmlPullParser.END_TAG: depth--; break; case XmlPullParser.START_TAG: depth ++; break;)))

Slik fungerer det:

  • Metoden gir et unntak hvis den gjeldende hendelsen ikke er START_TAG.
  • Den bruker START_TAG og alle hendelser opp til END_TAG.
  • For å være sikker på at den stopper ved riktig END_TAG og ikke det første møtemerket etter den opprinnelige START_TAG, holder den styr på hekkedybden.

Derfor, hvis det gjeldende elementet har nestede elementer, vil ikke dybdeverdien være 0 før parseren har behandlet alle hendelser mellom den opprinnelige START_TAG og dens tilsvarende END_TAG. Tenk for eksempel på hvordan analysatoren bommer et element som har 2 nestede elementer, og :

  • I den første passeringen gjennom while-løkken, den neste taggen som analysatoren møter etter dette er START_TAG for
  • I den andre passeringen gjennom while-løkken er den neste taggen som analysatoren møter END_TAG
  • I den tredje passeringen gjennom while-løkken er den neste taggen som analysatoren møter START_TAG ... Dybdeverdien økes til 2.
  • I den fjerde passeringen gjennom while-løkken er den neste taggen som analysatoren møter END_TAG... Dybdeverdien synker til 1.
  • På den femte og siste passeringen gjennom while-løkken er den neste taggen som analysatoren møter END_TAG... Dybden reduseres til 0, noe som indikerer det elementet ble hoppet over.

XML databehandling

Eksempelapplikasjonen mottar og analyserer en XML-feed til en AsyncTask. Behandlingen gjøres utenfor hovedgrensesnitttråden. Når behandlingen er fullført, oppdaterer applikasjonen brukergrensesnittet i hovedaktiviteten (NetworkActivity).

I utdraget nedenfor gjør loadPage ()-metoden følgende:

  • Initialiserer en strengvariabel med en URL-verdi som peker til en XML-feed.
  • Hvis brukerinnstillinger og nettverkstilkobling tillater det, kaller nye DownloadXmlTask ​​(). Kjør (url). Dette oppretter et nytt DownloadXmlTask-objekt (AsyncTask-underklasse) og utfører dens execute ()-metode, som laster ned og analyserer kanalen og returnerer et strengresultat som vil vises i brukergrensesnittet.
offentlig klasse NetworkActivity utvider aktivitet (offentlig statisk endelig streng WIFI = "Wi-Fi"; offentlig statisk endelig streng ANY = "Alle"; privat statisk endelig streng URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort = nyeste "; // Om det er en Wi-Fi-tilkobling. privat statisk boolesk wifiConnected = falsk; // Om det er en mobiltilkobling. privat statisk boolean mobileConnected = usant; // Om skjermen skal oppdateres. offentlig statisk boolsk refreshDisplay = true; public static String sPref = null; ... // Bruker AsyncTask for å laste ned XML-feeden fra stackoverflow.com. public void loadPage () (if ((sPref.equals (ANY)) && (wifiConnected || mobileConnected )) (ny DownloadXmlTask​(). execute (URL);) else if ((sPref.equals (WIFI)) && (wifiConnected)) (new DownloadXmlTask​(). execute (URL);) else (// vis feil))
  • doInBackground () utfører loadXmlFromNetwork ()-metoden. Den sender URL-en til kanalen som en parameter. loadXmlFromNetwork ()-metoden mottar og behandler kanalen. Når den er ferdig med behandlingen, sender den tilbake den resulterende strengen.
  • onPostExecute () tar den returnerte strengen og viser den i brukergrensesnittet.
// Implementering av AsyncTask brukes til å laste ned XML-feed fra stackoverflow.com. privat klasse DownloadXmlTask ​​utvider AsyncTask (@Override protected String doInBackground (String ... urls) (prøv (retur loadXmlFromNetwork (urls);) catch (IOException e) (retur getResources (). GetString (R.string.connection_error);) catch (XmlPullParserException e) ( return getResources (). getString (R.string.xml_error);)) @Override protected void onPostExecute (String result) (setContentView (R.layout.main); // Viser HTML-strengen i brukergrensesnittet via en WebView WebView myWebView = (WebView) findViewById (R.id.webview); myWebView.loadData (resultat, "tekst / html", null);))

Nedenfor er loadXmlFromNetwork ()-metoden som kalles fra DownloadXmlTask. Den gjør følgende:

  1. Oppretter en forekomst av StackOverflowXmlParser. Den oppretter også variabler for List Entry-objekter (oppføringer), og tittel, url og sammendrag, for å lagre verdiene hentet fra XML-feeden for disse feltene.
  2. Kaller downloadUrl (), som laster ned kanalen og returnerer den som en InputStream.
  3. Bruker StackOverflowXmlParser for å analysere InputStream. StackOverflowXmlParser fyller listeoppføringene med data fra feeden.
  4. Behandler en oppføringsliste og kombinerer feeddata med HTML-oppmerking.
  5. Returnerer HTML-strengen som vises i brukergrensesnittet til hovedaktiviteten, AsyncTask i onPostExecute ()-metoden.
// Laster opp XML fra stackoverflow.com, analyserer det og kombinerer det med // HTML-markering. Returnerer HTML-streng. privat streng loadXmlFromNetwork (String urlString) kaster XmlPullParserException, IOException (InputStream stream = null; // Instantiate parseren StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser (); oppføringer = null; Strengtittel = null; String url = null; String summary = null; Kalender rightNow = Calendar.getInstance (); DateFormat formatter = new SimpleDateFormat ("MMM dd h: mmaa"); // Sjekker om brukeren angir preferansen til å inkludere sammendragstekst SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences (this); boolean pref = sharedPrefs.getBoolean ("summaryPref", usant); StringBuilder htmlString = new StringBuilder (); htmlString.append ("

"+ getResources (). getString (R.string.page_title) +"

"); htmlString.append (" "+ getResources (). getString (R.string.updated) +" "+ formatter.format (rightNow.getTime ()) +""); prøv (stream = downloadUrl (urlString); entries = stackOverflowXmlParser.parse (stream); // Sørger for at InputStream er stengt etter at appen er // ferdig med å bruke den.) til slutt (if (stream! = null) (stream.close ();)) // StackOverflowXmlParser returnerer en liste (kalt "oppføringer") med oppføringsobjekter. // Hvert oppføringsobjekt representerer et enkelt innlegg i XML-feeden. // Denne delen behandler oppføringslisten for å kombinere hver oppføring med HTML-markering. // Hver oppføring vises i brukergrensesnittet som en lenke som eventuelt inkluderer // et tekstsammendrag. for (Oppføringsoppføring: oppføringer) (htmlString.append ("

"+ oppføring.tittel +"

"); // Hvis brukeren angir preferansen til å inkludere sammendragstekst, // legger den til på skjermen. Hvis (pref) (htmlString.append (entry.summary);)) returner htmlString.toString ();) // Gitt en strengrepresentasjon av en URL, setter opp en tilkobling og får // en input stream.private InputStream downloadUrl (String urlString) kaster IOException (URL url = new URL (urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection () ; conn.setReadTimeout (10000 / * milliseconds * /); conn.setConnectTimeout (15000 / * milliseconds * /); conn.setRequestMethod ("GET"); conn.setDoInput (true); // Starter spørringen conn.connect ( ); return conn.getInputStream ();)