Az XML elemzése lényegében azt jelenti, hogy végigmegyünk egy XML dokumentumon, és visszaadjuk a megfelelő adatokat. És bár minden több A webszolgáltatások JSON formátumban adják vissza az adatokat, de a legtöbb továbbra is XML-t használ, ezért fontos elsajátítani XML elemzés ha az elérhető API-k teljes skáláját szeretné használni.
A kiterjesztés használata SimpleXML a PHP-ben, amelyet a PHP 5.0-ban adtak hozzá, az XML-lel való munkavégzés nagyon könnyű és egyszerű. Ebben a cikkben megmutatom, hogyan kell csinálni.
Kezdjük a következő példával nyelvek.xml:
>
>
>
>
Ez az XML-dokumentum a programozási nyelvek listáját tartalmazza, néhány információval az egyes nyelvekről: a megvalósítás éve és a készítő neve.
Az első lépés az XML betöltése a függvények használatával simplexml_load_file(), vagy simplexml_load_string(). Ahogy a függvények neve is sugallja, az első egy fájlból, a második pedig egy karakterláncból tölti be az XML-t.
Mindkét függvény beolvassa a teljes DOM-fát a memóriába, és visszaad egy objektumot SimpleXMLElement. A fenti példában az objektum a $languages változóban van tárolva. Használhat funkciókat var_dump() vagy print_r() hogy részletes információkat kapjon a visszaküldött objektumról, ha úgy tetszik.
SimpleXMLElement objektum
[lang] => Tömb
[ 0 ] => SimpleXMLElementObject
[@attributes] => Tömb
[név] => C
[megjelent] => 1972
[ alkotó] => Dennis Ritchie
[ 1 ] => SimpleXMLElement objektum
[@attributes] => Tömb
[név] => PHP
[megjelent] => 1995
[ alkotó] => Rasmus Lerdorf
[ 2 ] => SimpleXMLElement objektum
[@attributes] => Tömb
[név] => Java
[megjelent] => 1995
[ alkotó] => James Gosling
)
)
Ez az XML tartalmazza a gyökérelemet nyelvek, amely három elemet tartalmaz lang. Minden tömbelem egy elemnek felel meg nyelv egy XML dokumentumban.
Egy objektum tulajdonságait az operátor segítségével érheti el -> . Például a $languages->lang egy SimpleXMLElement objektumot ad vissza, amely megfelel az első elemnek nyelv. Ez az objektum két tulajdonságot tartalmaz: megjelent és létrehozó.
$languages -> lang [ 0 ] -> megjelent ;
$languages -> lang [ 0 ] -> creator ;
A nyelvek listájának megjelenítése és tulajdonságaik megjelenítése nagyon egyszerű szabványos hurokkal, mint pl az egyes.
foreach ($languages> -> lang mint $lang ) (
printf (
""
,
$lang["név"] ,
$lang -> megjelent ,
$lang -> alkotó
)
;
}
Figyelje meg, hogyan jutottam hozzá a lang elem attribútumnevéhez, hogy megkapjam a nyelv nevét. Így elérheti a SimpleXMLElement objektumként ábrázolt elem bármely attribútumait.
A különféle webszolgáltatások XML-ével való munka során gyakran találkozhat elemnévterekkel. Változtassuk meg nyelvek.xml hogy példát mutassunk a névtér használatára:
xmlns:dc =>
>
>
>
Most elem Teremtő névtérbe helyezve dc, amely a http://purl.org/dc/elements/1.1/ címre mutat. Ha megpróbálja kinyomtatni a nyelvi alkotókat a korábbi kódunkkal, az nem fog működni. Az elemek névtereinek olvasásához a következő módszerek egyikét kell használnia.
Az első megközelítés az, hogy az URI-neveket közvetlenül a kódban használjuk, amikor az elem névterére hivatkozunk. A következő példa bemutatja, hogyan történik ez:
$dc = $nyelvek-> lang [1] -> gyermek( "http://purl.org/dc/elements/1.1/")
;
echo $dc -> creator ;
Módszer gyermekek() névteret vesz, és előtaggal kezdődő gyermekelemeket ad vissza. Két argumentumra van szükség, az első az XML névtér, a második pedig egy opcionális argumentum, amely alapértelmezés szerint az hamis. Ha a második argumentum értéke IGAZ, a névteret előtagként kezeli a rendszer. Ha FALSE, akkor a névteret az URL névtérként kezeli a rendszer.
A második megközelítés az URI-nevek beolvasása a dokumentumból, és az elem névterére történő hivatkozáskor használja őket. Valójában ez a legjobb módja az elemek elérésének, mert nem kell URI-ba kódolni.
$namespaces = $languages> -> getNamespaces (igaz) ;
$dc = $languages -> lang [ 1 ] -> children ($namespaces [ "dc" ] ) ;
echo $dc -> creator ;
Módszer GetNamespaces() előtagnevek és a hozzájuk tartozó URI-k tömbjét adja vissza. Szükség van egy további paraméterre, amely az alapértelmezett hamis. Ha telepíti, mint igaz, akkor ez a metódus a szülő és gyermek csomópontokban használt neveket adja vissza. Ellenkező esetben csak a szülőcsomópontban használt névtereket találja meg.
Most ismételheti a nyelvek listáját, így:
$languages = simplexml_load_file ("languages.xml" ) ;
$ns = $nyelvek -> getNamespaces (igaz) ;
foreach ($languages> -> lang mint $lang ) (
$dc = $lang -> gyermek ($ns [ "dc" ] ) ;
printf (
"
%s megjelent itt: %d, és %s hozta létre.
" ,Nézzünk egy példát, amelytől RSS-hírcsatorna érkezik YouTube csatornaés megjeleníti az összes videó linkjét. Ehhez vegye fel a kapcsolatot az alábbi címen:
http://gdata.youtube.com/feeds/api/users/xxx/uploads
Az URL az adott csatorna legújabb videóinak listáját adja vissza XML formátumban. Elemezzük az XML-t, és minden videóhoz megkapjuk a következő információkat:
Kezdjük az XML keresésével és betöltésével:
$channel = "Csatornanév" ;
$url = "http://gdata.youtube.com/feeds/api/users/". $csatorna. "/feltöltések" ;
$xml = file_get_contents ($url ) ;
$feed = simplexml_load_string ($xml ) ;
$ns = $feed -> getNameSpaces (true ) ;
Ha megnézed az XML feedet, láthatod, hogy több elem is van benne. entitás, amelyek mindegyike részletes információkat tárol a csatorna adott videójáról. De csak képek miniatűröket, videó címét és címét használjuk. Ez a három elem az elem gyermeke csoport, ami viszont gyermeke belépés:
…
…
…
>
…
Csak végigmegyünk az összes elemen belépés, és mindegyikhez kinyerjük a szükséges információkat. vegye figyelembe, hogy játékos, miniatűrÉs cím a média névtérben vannak. Így az előző példában leírtak szerint kell eljárnunk. A neveket a dokumentumból kapjuk, és a névteret használjuk, amikor az elemekre hivatkozunk.
foreach ($feed -> bejegyzés mint $entry ) (
$group = $bejegyzés -> gyermek ($ns [ "media" ] ) ;
$csoport = $csoport -> csoport ;
$thumbnail_attrs = $csoport -> thumbnail [ 1 ] -> attribútumok () ;
$image = $thumbnail_attrs [ "url" ] ;
$lejátszó = $csoport -> játékos -> attribútumok () ;
$link = $lejátszó["url"] ;
$cím = $csoport -> cím ;
printf ( ""
,
$lejátszó , $kép , $cím ) ;
}
Most, hogy tudja, hogyan kell használni SimpleXML Az XML adatok elemzéséhez fejlesztheti készségeit a különböző XML feedek különböző API-kkal történő elemzésével. Fontos azonban észben tartani, hogy a SimpleXML a teljes DOM-ot beolvassa a memóriába, így ha nagy adatkészletet elemez, elfogyhat a memória. Ha többet szeretne megtudni a SimpleXML-ről, olvassa el a dokumentációt.
Ha kérdése van, kérjük, használja a mi
Az Extensible Markup Language XML a dokumentumok géppel olvasható formában történő kódolására szolgáló szabályok összessége. Az XML az internetes adatcsere népszerű formátuma. A tartalmukat gyakran frissítő webhelyek, például híroldalak vagy blogok gyakran biztosítanak XML-hírcsatornát, hogy a külső programok értesüljenek a tartalomváltozásokról. Az XML adatok küldése és elemzése gyakori feladat a hálózati kapcsolattal rendelkező alkalmazásoknál. Ez a lecke elmagyarázza, hogyan kell XML-dokumentumokat elemezni és felhasználni az adataikat.
A hírcsatorna elemzésének első lépése annak eldöntése, hogy mely adatmezők érdeklik. Az elemző kivonja a megadott mezőket, és figyelmen kívül hagy minden mást.
Itt látható a csatornarészlet, amelyet a mintaalkalmazásban elemezni fog. A StackOverflow.com minden bejegyzése bejegyzéscímkeként jelenik meg a hírfolyamban, amely több beágyazott címkét tartalmaz:
Van egy alkalmazásom, amelyhez adatfájl szükséges...
A példaalkalmazás lekéri az adatokat a bejegyzés címkéjéből és annak cím, hivatkozás és összegzés alcímkéiből.
A következő lépés az elemző példányosítása és az elemzési folyamat elindítása. Ebben a kódrészletben az elemző úgy van inicializálva, hogy ne kezelje a névtereket, és a megadott InputStream-et használja bemenetként. Az elemzési folyamat a nextTag() meghívásával indul, és meghívja a readFeed() metódust, amely lekéri és feldolgozza az alkalmazást érdeklő adatokat:
Nyilvános osztály StackOverflowXmlParser ( // Nem használunk névtereket private static final String ns = null; public List parse(InputStream in) XmlPullParserException, IOException ( próbálja meg ( XmlPullParser parser = Xml.newPullParser();); parser.set.set. , false); parser.setInput(in, null); parser.nextTag(); return readFeed(elemző); ) végül (in.close(); ) ) ... )
A readFeed() metódus végzi el az adatfolyam feldolgozásának tényleges munkáját. Az "entry" címkével jelölt elemek jelentik a rekurzív csatornafeldolgozás kiindulópontját. Ha a következő címke nem belépési címke, akkor a rendszer kihagyja. A teljes "hírcsatorna" rekurzív feldolgozása után a readFeed() egy listát ad vissza, amely tartalmazza a hírfolyamból lekért bejegyzéseket (beleértve a beágyazott adatelemeket is). Ezt a listát az elemző visszaadja.
Private List readFeed(XmlPullParser parser) az XmlPullParserException, IOException (listabejegyzések = new ArrayList (); parser.require(XmlPullParser.START_TAG, ns, "feed"); while (parser.next() != XmlPullParser) (if. (parser.getEventType() != XmlPullParser.START_TAG) ( folytatás; ) String name = parser.getName(); // Az if (name.equals("entry") bejegyzési címkével kezdődik) ( entries.add( readEntry(elemző)); ) else ( skip(parser); ) ) adja vissza a bejegyzéseket; )
Az XML-hírcsatorna elemzésének lépései a következők:
Ez a részlet megmutatja, hogy az elemző hogyan elemzi a bejegyzést, a címet, a hivatkozást és az összefoglalót.
Nyilvános statikus osztály Bejegyzés ( publikus végleges Karakterlánc címe; publikus végleges Karakterlánc hivatkozás; nyilvános végleges Karakterlánc összefoglaló ; ) ) // Egy bejegyzés tartalmát elemzi. Ha címet, összefoglalót vagy hivatkozási címkét talál, adja át // a megfelelő "olvasási" metódusuknak a feldolgozáshoz. Ellenkező esetben hagyja ki a címkét. private Entry readEntry(XmlPullParser parser) XmlPullParserException, IOException (parser.require(XmlPullParser.START_TAG, ns, "entry"); String title = null; String summary = null; String link = null; while (parser.next()) ! = XmlPullParser.END_TAG) ( if (parser.getEventType() != XmlPullParser.START_TAG) ( folytatás; ) Karakterlánc neve = parser.getName(); if (name.equals("title")) ( title = readTitle(parser) ; ) else if (name.equals("összefoglaló")) ( summary = readSummary(parser); ) else if (name.equals("link")) ( link = readLink(elemző); ) else ( skip(parser) ; ) ) return new Entry(cím, összefoglaló, link); ) // Feldolgozza a címcímkéket a hírfolyamban. private String readTitle(XmlPullParser parser) IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "title"); String title = readText(parser); parser.require(XmlPullParser.END_TAG, n) parancsot return title; ) // Feldolgozza a linkcímkéket a hírfolyamban. private String readLink(XmlPullParser parser) IOException, XmlPullParserException (String link = ""; parser.require(XmlPullParser.START_TAG, ns, "link"); String tag = parser.getName(); String relType = parser.getAttributeValue , "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; ) // Feldolgozza az összefoglaló címkéket a hírfolyamban. private String readSummary(XmlPullParser parser) IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "summary"); String summary = readText(parser); parser.require(XmlPullParser.END_TAG, n); return summary; ) // A title és summary címkék szöveges értékeit kivonja. private String readText(XmlPullParser elemző) IOException, XmlPullParserException ( String result = ""; if (parser.next() == XmlPullParser.TEXT) ( result = parser.getText(); parser.nextTag(); ) eredményt ad vissza; ) ... )
A fent leírt XML-elemzési lépések egyikében az elemző kihagyja azokat a címkéket, amelyekre nem vagyunk kíváncsiak. Alább látható a skip() metódus elemző kódja:
A privát void skip(XmlPullParser elemző) az XmlPullParserException, IOException paramétert dobja ( if (parser.getEventType() != XmlPullParser.START_TAG) ( új IllegalStateException(); ) int mélység = 1; while (depth != 0) ( kapcsoló next()) ( XmlPullParser eset.END_TAG: mélység--; törés; XmlPullParser kisbetű.START_TAG: mélység++; törés; ) ) )
Így működik:
Így, ha az aktuális elem beágyazott elemeket tartalmaz, a mélység nem lesz 0, amíg az elemző fel nem dolgozott minden eseményt az eredeti START_TAG és a megfelelő END_TAG között. Vegyük például, hogyan ugrik az elemző
A példaalkalmazás fogadja és elemzi az XML-hírcsatornát egy AsyncTask-ban. A feldolgozás a fő felhasználói felületen kívül történik. A feldolgozás befejeztével az alkalmazás frissíti a felhasználói felületet a fő tevékenységben (NetworkActivity).
Az alábbi részletben a loadPage() metódus a következőket teszi:
Az alábbiakban látható a loadXmlFromNetwork() metódus, amelyet a DownloadXmlTask-ból hívnak meg. A következőket teszi:
" + bejegyzés.cím + "
"); // Ha a felhasználó úgy állítja be az összefoglaló szöveget, // hozzáadja a megjelenítéshez. if (pref) ( htmlString.append(entry.summary); ) ) return htmlString.toString(); ) // Adott egy URL karakterlánc-reprezentációja, létrehoz egy kapcsolatot, és // kap egy bemeneti adatfolyamot.private InputStream downloadUrl(String urlString) IOExceptiont dob ( URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url(.openConnection ; conn.setReadTimeout(10000 /* ezredmásodperc */); conn.setConnectTimeout(15000 /* ezredmásodperc */); conn.setRequestMethod("GET"); conn.setDoInput(true); // Elindítja a conn.connect( ); return conn.getInputStream(); )Ebben a cikkben egy példát mutatok be egy nagy XML-fájl elemzésére. Ha a szerverednek (hostingnek) nincs tiltva a szkript futási idejének növelése, akkor legalább gigabájt súlyú XML fájlt is elemezhetsz, én személy szerint csak a 450 megabájt súlyú ózon fájlokat elemeztem.
Két probléma adódik a nagy XML-fájlok elemzésekor:
1. Nincs elég memória.
2. Nincs elegendő idő a szkript működéséhez.
A második idővel kapcsolatos probléma megoldható, ha ezt nem tiltja a szerver.
De a memória problémáját nehéz megoldani, még akkor is, ha a saját szerveréről beszélünk, akkor az 500 megabájtos fájlok mozgatása nem túl egyszerű, és még tárhelyen és VDS-en sem egyszerűen nem növelheti a memóriát.
A PHP számos beépített XML feldolgozási opcióval rendelkezik - SimpleXML, DOM, SAX.
Mindezeket a lehetőségeket számos példacikk részletezi, de mindegyik példa bemutatja, hogyan kell dolgozni egy teljes XML-dokumentummal.
Íme egy példa, egy XML-fájlból kapunk egy objektumot
$xml = simplexml_load_file ("1.xml" ); ?>
Most már feldolgozhatja ezt az objektumot, DE...
Amint látja, a teljes XML-fájlt a rendszer beolvassa a memóriába, majd mindent egy objektummá értelmez.
Vagyis minden adat a memóriába kerül, és ha a lefoglalt memória nem elegendő, akkor a szkript leáll.
Ez az opció nem alkalmas nagy fájlok feldolgozására, soronként kell olvasni a fájlt, és sorra kell feldolgozni ezeket az adatokat.
Ugyanakkor az adatok feldolgozása során az érvényesség ellenőrzése is megtörténik, így vissza kell tudni görgetni, például érvénytelen XML fájl esetén törölni kell az összes bevitt adatbázist, vagy két átmegy a fájlon, először beolvassa az érvényességet, majd olvassa el az adatok feldolgozásához.
Itt van egy elméleti példa egy nagy XML-fájl elemzésére.
Ez a szkript beolvas egy karaktert egy fájlból, ezeket az adatokat blokkokba gyűjti és elküldi az XML elemzőnek.
Ez a megközelítés teljesen megoldja a memóriaproblémát, és nem okoz terhelést, de idővel súlyosbítja a problémát. Az alábbiakban olvashat arról, hogyan próbálja meg megoldani a problémát idővel.
webi_xml($file) függvény
{
########
### adatkezelési funkció
{
nyomtatás $adatok ;
}
############################################
{
nyomtatás $név ;
print_r($attrs);
}
## záró tag funkció
függvény endElement ($elemző , $név )
{
nyomtatás $név ;
}
############################################
($xml_parser , "adatok" );
// fájl megnyitása
$fp = fopen($file , "r" );
$perviy_vxod = 1 ; $adat = "" ;
{
$simvol = fgetc($fp); $adat .= $simvol ;
if($simvol != ">" ) ( folytatás;)
"
);
$perviy_vxod
=
0
;}
visszhang"
szünet;
}
$adat = "" ;
}
fclose($fp);
webi_xml("1.xml");
?>
Ebben a példában mindent egy webi_xml () függvénybe raktam, és a hívása a legalul látható.
Maga a szkript három fő funkcióból áll:
1. Egy függvény, amely elkapja a startElement() címke nyitását
2. Egy függvény, amely elkapja az endElement() címke bezárását
3. És az adatokat fogadó függvény data() .
Tegyük fel, hogy az 1.xml fájl tartalma egy recept
<
title
>egyszerű kenyér
title
>
<
ingredient amount
=
"3"
unit
=
"стакан"
>Liszt
ingredient
>
<
ingredient amount
=
"0.25"
unit
=
"грамм"
>Élesztő
ingredient
>
<
ingredient amount
=
"1.5"
unit
=
"стакан"
>meleg víz
ingredient
>
<
ingredient amount
=
"1"
unit
=
"чайная ложка"
>Só
ingredient
>
<
instructions
>
<
step
>
Az összes hozzávalót összekeverjük és alaposan összegyúrjuk.
step
>
<
step
>
Fedjük le egy ruhával, és hagyjuk egy órán át meleg szobában.
step
>
<
step
>
Ismét összegyúrjuk,
tepsire tesszük és betesszük a sütőbe.
step
>
<
step
>
Látogassa meg a webhely webhelyét
step
>
instructions
>
recipe
>
Kezdjük a webi_xml("1.xml") általános függvény meghívásával;
Ebben a funkcióban az elemző elindul, és az összes címkenév le lesz fordítva nagybetűs hogy minden címkének ugyanaz a kis- és nagybetűje legyen.
$xml_parser = xml_parser_create();
xml_parser_set_option ($xml_parser , XML_OPTION_CASE_FOLDING , true );
Most megadjuk, hogy mely funkciók fognak működni a címke megnyitásának, bezárásának és adatfeldolgozásának elfogására
xml_set_element_handler($xml_parser , "startElement" , "endElement" );
xml_set_character_data_handler($xml_parser , "adatok" );
Következik a megadott fájl megnyitása, ismétlés a fájlon egy karakterrel, és minden karakter hozzáadódik a karakterlánc változóhoz, amíg meg nem találja a karaktert >
.
Ha ez az első hozzáférés a fájlhoz, akkor minden, ami a fájl elején felesleges, törlődik az út során, minden, ami előtte áll.
, ezzel a címkével kell kezdődnie az XML-nek.
Az első alkalommal, amikor egy karakterlánc-változó gyűjt egy karakterláncot
És küldje el az elemzőnek
xml_parse ($xml_parser , $data , feof ($fp ));
Az adatok feldolgozása után a karakterlánc-változó alaphelyzetbe áll, és újra kezdődik az adatok karakterláncba gyűjtése, és másodszor jön létre egy karakterlánc
A harmadikban
a negyedikben
egyszerű kenyér
Kérjük, vegye figyelembe, hogy a karakterlánc-változót mindig a befejezett címke alkotja >
és nem szükséges például nyitott és zárt címkéket adatokkal elküldeni a dekomposernek
Ennek a kezelőnek fontos, hogy egy egész bontatlan címkét kapjon, legalább egy nyitott címkét, és a következő lépésben egy zárt címkét, vagy azonnal kapjon 1000 sort a fájlból, mindegy, a lényeg, hogy a címke nem törik például
le>Egyszerű kenyér
Így nem lehet adatot küldeni a kezelőnek, mert a címke elromlott.
Ki lehet találni egy saját módszert a kezelőnek való adatküldésre, például gyűjts össze 1 megabájt adatot és küldd el a kezelőnek a sebesség növelése érdekében, csak ügyelj arra, hogy a címkék mindig véget érjenek, és az adatok törhetők
kenyér
Így, részletekben, tetszés szerint küldheti nagy fájl a felvezetőnek.
Most nézzük meg, hogyan dolgozzák fel ezeket az adatokat, és hogyan szerezhetők be.
Kezdve a nyitó címkék funkcióval startElement ($parser , $name , $attrs )
Tegyük fel, hogy a feldolgozás elérte a sort
<
ingredient amount
=
"3"
unit
=
"стакан"
>Liszt
ingredient
>
Ekkor a függvényen belül a $name változó egyenlő lesz hozzávaló vagyis a nyitott címke neve (az ügy még nem érte el a címke lezárását).
Benne is ez az eset a $attrs címke attribútumainak tömbje elérhető lesz, amelyben lesznek adatok mennyiség = "3" és egység = "üveg".
Ezt követően a nyitott címke adatait feldolgozta a függvény adatok ($parser , $data )
A $data változó mindent tartalmaz, ami a nyitó és záró címke között van, esetünkben ez a Muk szöveg
És a karakterláncunk függvény általi feldolgozása befejeződött endElement ($elemző , $név )
Ez a zárt címke neve, esetünkben a $name egyenlő lesz hozzávaló
Utána pedig ismét körbejárt az egész.
A fenti példa csak az XML feldolgozás elvét mutatja be, de a valós alkalmazáshoz azt véglegesíteni kell.
Általában nagy XML-t kell elemezni ahhoz, hogy adatokat vigyünk be az adatbázisba, és a megfelelő adatfeldolgozáshoz tudnia kell, hogy az adatok melyik nyitott címkéhez tartoznak, milyen szintű címkebeágyazás, és mely címkék vannak nyitva a fenti hierarchiában. Ezen információk birtokában probléma nélkül tudja megfelelően feldolgozni a fájlt.
Ehhez több globális változót kell bevezetnie, amelyek információkat gyűjtenek a nyitott címkékről, a beágyazásról és az adatokról.
Íme egy használható példa
webi_xml($file) függvény
{
globális $webi_depth ; // számláló a fészkelési mélység nyomon követéséhez
$webi_mélység = 0 ;
globális $webi_tag_open ; // tartalmazni fog egy tömböt az open in Ebben a pillanatban címkéket
$webi_tag_open = array();
globális $webi_data_temp ; // ez a tömb egy címke adatait fogja tartalmazni
####################################################
### adatkezelési funkció
függvényadatok ($parser , $data )
{
globális $webi_depth ;
globális $webi_tag_open ;
globális $webi_data_temp ;
// adatok hozzáadása a tömbhöz egymásba ágyazással és jelenleg megnyitott címkével
$webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "data" ].= $adat ;
}
############################################
####################################################
### nyitó címke funkció
függvény startElement ($parser , $name , $attrs )
{
globális $webi_depth ;
globális $webi_tag_open ;
globális $webi_data_temp ;
// ha a beágyazási szint még nem nulla, akkor egy címke már nyitva van
// és az abból származó adatok már a tömbben vannak, akkor ezeket feldolgozhatja
ha ($webi_depth)
{
"
;
nyomtatás"
"
;
print_r($webi_tag_open); // nyitott címkék tömbje
nyomtatás"
// az adatok feldolgozása után törölje azokat a memória felszabadítása érdekében
unset($GLOBALS [ "webi_data_temp" ][ $webi_depth ]);
}
// most megkezdődött a következő címke megnyitása, és a további feldolgozás a következő lépésben történik
$webi_depth++; // fészkelődés növelése
$webi_tag_open [ $webi_depth ]= $név ; // nyitott címke hozzáadása az információs tömbhöz
$webi_data_temp [ $webi_depth ][ $name ][ "attrs" ]= $attrs ; // most adjunk hozzá címkeattribútumokat
}
###############################################
#################################################
## záró tag funkció
függvény endElement ($elemző , $név ) (
globális $webi_depth ;
globális $webi_tag_open ;
globális $webi_data_temp ;
// itt kezdődik az adatfeldolgozás, például az adatbázisba való felvétel, fájlba mentés stb.
// A $webi_tag_open nyitott címkék láncát tartalmazza beágyazási szint szerint
// például a $webi_tag_open[$webi_depth] tartalmazza annak a nyitott tagnek a nevét, amelynek információi jelenleg feldolgozás alatt állnak
// $webi_depth címke beágyazási szintje
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["attrs"] címkeattribútumok tömbje
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["data"] címkeadatok
Nyomtassa ki az "adatokat". $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" ]);
nyomtatás"
"
;
print_r($webi_tag_open);
nyomtatás"
Unset($GLOBALS [ "webi_data_temp" ]); // az adatok feldolgozása után töröljük a tömböt az adatok egészével, mivel a címke zárva volt
unset($GLOBALS [ "webi_tag_open" ][ $webi_depth ]); // információ eltávolítása erről a megnyitott címkéről... mivel bezárta
$webi_depth --; // csökkenti a beágyazást
}
############################################
$xml_parser = xml_parser_create();
xml_parser_set_option ($xml_parser , XML_OPTION_CASE_FOLDING , true );
// adja meg, hogy mely funkciók működjenek a címkék megnyitásakor és bezárásakor
xml_set_element_handler($xml_parser , "startElement" , "endElement" );
// függvény megadása az adatokkal való munkavégzéshez
xml_set_character_data_handler($xml_parser , "adatok" );
// fájl megnyitása
$fp = fopen($file , "r" );
$perviy_vxod = 1 ; // jelző a fájl első bemenetének ellenőrzéséhez
$adat = "" ; // itt összegyűjtjük a fájlból az adatok egy részét, és elküldjük az xml elemzőnek
// ciklus a fájl végéig
míg (! feof ($fp ) és $fp )
{
$simvol = fgetc($fp); // beolvas egy karaktert a fájlból
$adat .= $simvol ; // adjuk hozzá ezt a karaktert a küldendő adatokhoz
// ha a karakter nem a végcímke, akkor térjen vissza a ciklus elejére, és adjon hozzá még egy karaktert az adatokhoz, és így tovább, amíg meg nem találja a végcímkét
if($simvol != ">" ) ( folytatás;)
// ha a záró címkét megtalálták, most küldje el ezeket az összegyűjtött adatokat feldolgozásra
// ellenőrizze, hogy ez az első bejegyzés a fájlban, majd töröljön mindent, ami a címke előtt van
// mivel néha előfordulhat, hogy az XML kezdete előtt szemét található (ügyetlen szerkesztők, vagy a fájlt egy másik szerverről kapta a szkript)
if($perviy_vxod ) ( $data = strstr ($data , ""
);
$perviy_vxod
=
0
;}
// most adatokat dobunk az xml elemzőbe
if (! xml_parse ($xml_parser , $data , feof ($fp ))) (
// itt lehet feldolgozni és érvényességi hibákat kérni...
// amint hiba történik, az elemzés leáll
visszhang"
XML-hiba: " .xml_error_string (xml_get_error_code ($xml_parser ));
visszhang "vonalnál" . xml_get_current_line_number($xml_parser );
szünet;
}
// elemzés után az összegyűjtött adatokat kidobjuk a ciklus következő lépéséhez.
$adat = "" ;
}
fclose($fp);
xml_parser_free($xml_parser );
// globális változók törlése
unset($GLOBALS [ "webi_depth" ]);
unset($GLOBALS [ "webi_tag_open" ]);
unset($GLOBALS [ "webi_data_temp" ]);
webi_xml("1.xml");
?>
Az egész példát megjegyzések kísérték, most teszteljetek és kísérletezzetek.
Kérjük, vegye figyelembe, hogy az adatkezelési funkcióban az adatok nem egyszerűen bekerülnek a tömbbe, hanem a " .="
mivel az adatok nem biztos, hogy teljes formában érkeznek, és ha csak egy feladatot adsz meg, akkor időről időre darabokban kapod meg az adatokat.
Nos, ennyi, most tetszőleges méretű fájl feldolgozásakor lesz elegendő memória, de a szkript futási ideje többféleképpen növelhető.
Szúrjon be egy függvényt a szkript elejére
set_time_limit(6000);
vagy
ini_set("max_végrehajtási_idő" , "6000" );
Vagy adjon hozzá szöveget a .htaccess fájlhoz
php_value max_execution_time 6000
Ezek a példák a szkript futási idejét 6000 másodpercre növelik.
Az időt ilyen módon csak kikapcsolt csökkentett módban növelheti.
Ha van hozzáférése a php.ini szerkesztéséhez, növelheti az időt a következővel
maximális_végrehajtási_idő = 6000
Például a masterhost tárhelyen az írás idején a szkriptidő növelése tilos, annak ellenére biztonságos mód, de ha profi vagy, építhetsz php-t a masterhost-ra, de ez nem szerepel ebben a cikkben.
Most az XML-lel való munkát fogjuk tanulmányozni. Az XML a webhelyek közötti adatcsere formátuma. Nagyon hasonlít a HTML-hez, csak az XML engedélyezi a saját címkéit és attribútumait.
Miért van szükség XML-re az elemzéshez? Néha előfordul, hogy az elemezni kívánt webhelynek van egy API-ja, amely lehetővé teszi, hogy különösebb erőfeszítés nélkül megkapja, amit akar. Ezért azonnal tanácsot adjon – a webhely elemzése előtt ellenőrizze, hogy van-e API-ja.
Mi az API? Ez egy olyan funkciókészlet, amellyel kérést küldhet erre az oldalra, és megkaphatja a kívánt választ. Ez a válasz leggyakrabban XML formátumban érkezik. Tehát kezdjük el tanulmányozni.
Tegyük fel, hogy van XML-je. Lehet karakterláncban, fájlban tárolva, vagy kérésre kiszolgálható egy adott URL-re.
Legyen az XML egy karakterláncban tárolva. Ebben az esetben ebből a sorból kell létrehoznia egy objektumot a segítségével új SimpleXMLElement:
$str = "
Most van egy változónk $xml elemzett XML-lel rendelkező objektum kerül tárolásra. Az objektum tulajdonságainak elérésével hozzáférhet az XML-címkék tartalmához. Hogyan pontosan - egy kicsit lejjebb elemezzük.
Ha az XML fájlban van tárolva, vagy egy URL elérésével tér vissza (ami leggyakrabban így van), akkor használja a függvényt simplexml_load_file amely ugyanazt a tárgyat teszi $xml:
$xml = simplexml_load_file(fájl elérési útja vagy url);
Az alábbi példákban az XML-t fájlban vagy URL-ben tároljuk.
Legyen megadva a következő XML:
Nézzük meg egy alkalmazott nevét, életkorát és fizetését:
$xml = simplexml_load_file(fájl elérési útja vagy url); echo $xml->név; //megjeleníti a "Kolya" echo $xml->age; //kimenetek 25 echo $xml->fizetés; //1000-et ad ki
Amint látható, a $xml objektum a címkéknek megfelelő tulajdonságokkal rendelkezik.
Talán észrevetted, hogy a címke
$xml = simplexml_load_file(fájl elérési útja vagy url); echo $xml->név; //megjeleníti a "Kolya" echo $xml->age; //kimenetek 25 echo $xml->fizetés; //1000-et ad ki
Az XML-ben csak egy gyökércímke lehet, akárcsak a gyökércímke sima HTML-ben.
Módosítsuk egy kicsit az XML-ünket:
Ebben az esetben egy hívásláncot kapunk:
$xml = simplexml_load_file(fájl elérési útja vagy url); echo $xml->dolgozó->név; //megjeleníti "Kolya" echo $xml->worker->age; //25-öt ad ki echo $xml->dolgozó->bér; //1000-et ad ki
Néhány adatot tároljunk attribútumokban:
$xml = simplexml_load_file(fájl elérési útja vagy url); echo $xml->dolgozó["név"]; //megjeleníti "Kolya" echo $xml->worker["age"]; //kimenet 25 echo $xml->dolgozó["fizetés"]; //kimenetek 1000 echo $xml->worker; //kiírja az "1-es számot"
Az XML-ben a kötőjellel ellátott címkék (és attribútumok) megengedettek. Ebben az esetben az ilyen címkék a következőképpen érhetők el:
$xml = simplexml_load_file(fájl elérési útja vagy url); echo $xml->dolgozó->(keresztnév); //megjeleníti "Kolya" echo $xml->worker->(last-name); //megjeleníti az "Ivanov" kifejezést
Most ne egy munkásunk legyen, hanem több. Ebben az esetben egy foreach ciklussal iterálhatjuk az objektumunkat:
$xml = simplexml_load_file(fájl elérési útja vagy url); foreach ($xml mint $worker) ( echo $worker->name; //kiírja: "Kolya", "Vasya", "Petya" )
Ha nem érzi jól magát egy objektummal dolgozni, a következő trükkel átalakíthatja azt normál PHP tömbbé:
$xml = simplexml_load_file(fájl elérési útja vagy url); var_dump(json_decode(json_encode($xml), true));
Egy webhely gyakran tartalmaz egy sitemap.xml fájlt. Ez a fájl a webhely összes oldalára mutató hivatkozásokat tárol a keresőmotorok általi indexelés megkönnyítése érdekében (az indexelés valójában a webhely Yandex és Google általi elemzése).
Általában nem nagyon kell törődnünk azzal, hogy miért van szükség erre a fájlra, a lényeg az, hogy ha létezik, akkor ne mászhasson fel az oldal oldalain semmilyen trükkös módszerrel, hanem egyszerűen használja ezt a fájlt.
A fájl meglétének ellenőrzése: elemezzük a site.ru webhelyet, majd keresse fel a site.ru/sitemap.xml fájlt a böngészőben - ha lát valamit, akkor ott van, és ha nem látja, akkor sajnos.
Ha van webhelytérkép, akkor az XML formátumban tartalmazza a webhely összes oldalára mutató hivatkozásokat. Nyugodtan vegye ezt az XML-t, elemezze, különítse el a szükséges oldalakra mutató hivatkozásokat az Ön számára megfelelő módon (például a pók módszernél leírt URL elemzésével).
Ennek eredményeként megkapja az elemzéshez szükséges linkek listáját, és csak rá kell mennie, és elemeznie kell a szükséges tartalmat.
További információ a sitemap.xml eszközről a wikipédiában.
Kezdje el a problémák megoldását az alábbi linken: feladatok az órán.
Ha minden eldőlt, folytassa egy új téma tanulmányozásával.