Pro mnoho programátorů Delphi je ukládání nastavení spojeno s používáním INI soubory ve svých programech. Použití této metody ve více či méně závažných projektech je třeba se vyhnout, protože omezuje flexibilitu, což brání dalšímu rozšiřování programu. Je třeba říci, že tento přístup je poměrně populární díky snadnému použití a přítomnosti vestavěných nástrojů ve vývojovém prostředí.
Nicméně strukturované XML soubory. Jejich výhodou je, že počet parametrů nemusí být pevně daný. Abyste tomu lépe porozuměli, zvažte konkrétní příklad.
V programu USearch se po kliknutí na záznam zobrazí kontextové menu, ve kterém je zobrazen seznam položek. Tyto položky jsou příkazy, které se načítají ze souboru nastavení. V případě, že byla nastavení uložena v INI soubor, pak by program mohl uložit a načíst určitý počet příkazů, například 10 nebo 50. Jakmile bude vyžadována větší hodnota, budete muset přepsat kód a znovu jej odpovídajícím způsobem zkompilovat.
Použití přístupu pomocí XML soubory, budeme moci dynamicky načítat všechny parametry sekce. Konfigurační soubor se navíc stane elegantnějším, bez nadbytečného číslování parametrů. Ale, standardní prostředky pracovat s XML Delphi má mnoho nevýhod, proto doporučuji používat standardní knihovna MSXML... Obvykle je standardně součástí operační systémy Rodina Windows.
Chcete-li se připojit MSXML, potřebujeme vygenerovat soubor rozhraní se seznamem všech funkcí jeho importem ze serveru COM. O tom, jak importovat rozhraní, bylo napsáno mnoho podrobných článků, ale doporučuji vám stáhnout soubor MSXML2_TLB.PAS připraven k použití. Po stažení soubor umístěte vedle svého projektu nebo jej přesuňte do složky lib prostředí Delphi. Modul tedy budou moci používat všechny vytvořené programy MSXML, stačí přidat řádek MSXML2_TLB k použití.
Pro srozumitelnost zvažte následující příklad použití této knihovny:
Postup LoadData; var XMLDoc: DOMDocument; Kořen: IXMLDOMElement; begin XMLDoc: = CoDOMDocument.Create; XMLDoc.Load ("settins.xml"); Kořen: = XMLDoc.DocumentElement; ShowMessage (Root.SelectSingleNode ("velikost / šířka"). Text); Kořen: = nula; XMLDoc: = nula; konec;
Nejprve se vytvoří instance třídy DOMDocument a poté se do paměti načte obsah souboru settings.xml. Jelikož dle normy jakákoliv XML soubor musí obsahovat kořenovou značku (in v tomto případě config), pak jej musíme získat pomocí funkce DocumentElement... Poté se obsah zobrazí mezi značkami.
Zde je aplikována metoda SelectSingleNode, která jako parametr bere řetězec
Navzdory tomu, že téma práce s XML v Delphi bylo na internetu hojně diskutováno, dotazy na toto téma se často objevují na nejrůznějších fórech.
Napsal jsem to také, ale rád bych se vrátil k reálnému případu rychlého parsování XML souboru a extrahování dat, které jsem dnes dělal v práci. Získat potřebná data mi netrvalo déle než 5 minut.
Pozadí. Dnes jsem potřeboval zpracovat data o nainstalované programy na počítačích uživatelů (ano, ano, identifikujeme piráty :)). Technické oddělení mi poskytlo tyto informace získané od nic netušících uživatelů přes síť pomocí WMI. Program, který použili, generuje zprávy XML formát... V souladu s tím mi přinesli horu XML souborů s poměrně složitou strukturou, ze které jsem musel vytáhnout pouze název nainstalovaných softwarových produktů. Léčba . Když jsem si ručně prohlédl několik souborů, uvědomil jsem si, že nebude trvat dlouho, než zestárnu, a rozhodl jsem se napsat malý konvertor. Po spuštění Delphi jsem z úložiště vybral objekt XML DataBinding a vložil do něj jeden ze souborů. Ponechal jsem všechna nastavení a parametry ve výchozím nastavení a v důsledku toho modul s velké množství třídy a rozhraní pro přístup k prvkům tohoto souboru XML. Strukturou tříd jsem se dlouho neobtěžoval řešit, hned jsem přešel k psaní převodníku. V nové konzolové aplikaci jsem napsal docela jednoduchý kód:
program XML2TXT;
používá
Formuláře,
Třídy, SysUtils,
SoftwareXML v "SoftwareXML.pas";
procedura CovertXML2Text;
var
softbase: IXMLSTDSoftwareType;
i: celé číslo;
sr: TSearchRec;
CurDir: řetězec;
ExportFile: TStringList;
začít
CurDir: = IncludeTrailingPathDelimiter (ExtractFilePath (Application.ExeName));
pokud FindFirst (CurDir + "*. xml", faAnyFile, sr) = 0, pak
opakovat
ExportFile: = TStringList.Create;
softbase: = LoadSTDSoftware (Pchar (CurDir + sr.Name));
for i: = 0 to softbase.InstalledSoftware.source.software.Count - 1 do
ExportFile.Add (softbase.InstalledSoftware.source.software [i] .DisplayName);
ExportFile.Sort;
ExportFile.SaveToFile (CurDir + softbase.InstalledSoftware.Source.servername + ". Txt");
ExportFile.Free;
dokud FindNext (sr) 0;
konec;
začít
Application.Initialize;
CovertXML2Text;
konec.
V důsledku toho jsem pro každý počítač v mřížce získal jeden textový editor obsahující seznam nainstalovaného softwaru.
Mám pocit, že tento kód bude vyžadovat nějaké vysvětlení. Proč jsem například použil modul Forms v konzolové aplikaci a zavolal proceduru Application.Initialize;?
Je to vlastně jednoduché – jde o malý hack, který vám umožňuje používat XML Data Binding v konzolové aplikaci. Protože tvrdošíjně odmítala inicializovat třídu pro práci s XML. Ještě jsem nepřišel na skutečné důvody - dnes byl důležitý čas, už jsem s touto chybou strávil 4 z 5 minut. :) Myslím, že později se tímto problémem zabývat a napsat, co je skutečným důvodem.
Podivná třída softbase byla vytvořena ze souboru XML - to je název kořenového prvku a softbase.InstalledSoftware.source.software [i] .DisplayName je pouze procházení vnořenými prvky k požadovanému prvku a získávání jeho hodnoty.
Takhle jeden z nej rychlé způsoby práce s XML v Delphi.
XML se stále více používá k ukládání informací a jejich výměně mezi aplikacemi a webovými stránkami. Mnoho aplikací používá tento jazyk jako základní jazyk pro ukládání dat, zatímco jiné jej používají pro export a import dat XML. Je tedy čas, aby vývojáři začali přemýšlet o tom, jak lze data XML použít v jejich vlastních aplikacích.
V tomto článku se podíváme na XML Document Object Model (DOM) a implementaci XML DOM od společnosti Microsoft.
XML DOM je objektový model, který poskytuje vývojářům objekty pro načítání a zpracování souborů XML. Objektový model se skládá z následujících základních objektů: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap a XMLDOMParseError. Každý z těchto objektů (kromě XMLDOMParseError) obsahuje vlastnosti a metody, které vám umožňují získat informace o objektu, manipulovat s hodnotami a strukturou objektu a procházet strukturou dokumentu XML.
Podívejme se na hlavní objekty XML DOM a ukažme si některé příklady jejich použití v Borland Delphi.
Použití XML DOM v Borland Delphi
Abyste mohli používat Microsoft XML DOM v aplikacích Delphi, musíte k projektu připojit příslušnou knihovnu typů. K tomu spustíme příkaz Projekt | Import knihovny typů a v dialogovém okně Import knihovny typů vyberte knihovnu Microsoft XML verze 2.0 (verze 2.0), která se obvykle nachází v souboru Windows \ System \ MSXML.DLL.
Po kliknutí na tlačítko Create Unit se vytvoří modul rozhraní MSXML_TLB, který nám umožní používat objekty XML DOM: DOMDocument, XMLDocument, XMLHTTPRequest a řadu dalších, implementovaných v knihovně MSXML.DLL. Odkaz na modul MSXML_TLB musí být v seznamu Použití.
XML DOM zařízení
Objektový model dokumentu představuje dokument XML ve stromové struktuře větví. XML DOM API umožňují aplikacím procházet strom dokumentů a manipulovat s jeho větvemi. Každá větev může mít specifický typ (DOMNodeType), podle kterého se určuje nadřazená a podřízená větev. Většina dokumentů XML obsahuje větve typu element, atribut a text. Atributy jsou speciálním druhem větvení a nejsou podřízenými větvemi. Chcete-li spravovat atributy, použijte speciální metody poskytované objekty XML DOM.
Kromě implementace rozhraní doporučených konsorciem World Wide Web Consortium (W3C), Microsoft XML DOM obsahuje metody, které podporují XSL, XSL vzory, jmenné prostory a datové typy. Například metoda SelectNodes umožňuje použít syntaxi vzoru XSL k nalezení větví v určitém kontextu a metoda TransformNode podporuje použití XSL k provádění transformací.
Test XML dokumentu
Jako příklad dokumentu XML si vezměme adresář hudebního CD-ROM, který má následující strukturu:
Nyní jsme připraveni začít zkoumat objektový model XML DOM, počínaje objektem XMLDOMDocument.
Dokument XML - Objekt XMLDOMDocument
Práce s dokumentem XML začíná jeho načtením. K tomu používáme metodu Load, která má pouze jeden parametr, který určuje URL načítaného dokumentu. Při načítání souborů z lokálního disku se zadává pouze celý název souboru (soubor: /// protokol lze v tomto případě vynechat). Pokud je dokument XML uložen jako řetězec, použijte k načtení dokumentu metodu LoadXML.
Vlastnost Async se používá k řízení způsobu načítání dokumentu (synchronního nebo asynchronního). Ve výchozím nastavení je tato vlastnost nastavena na hodnotu True, což znamená, že dokument je načten asynchronně a řízení je vráceno aplikaci před úplným načtením dokumentu. V opačném případě se dokument načte synchronně a pak musíte zkontrolovat hodnotu vlastnosti ReadyState, abyste zjistili, zda se dokument načetl nebo ne. Můžete také vytvořit obslužnou rutinu pro událost OnReadyStateChange, která převezme řízení, když se změní hodnota vlastnosti ReadyState.
Následující text ukazuje, jak načíst dokument XML pomocí metody Load:
Používá ... MSXML_TLB ... procedure TForm1.Button1Click (Sender: TObject); var XMLDoc: IXMLDOMDocument; begin XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // // Zde se nachází kód, který // manipuluje s dokumentem XML a jeho větvemi // XMLDoc: = Nil; konec;
Po načtení dokumentu máme přístup k jeho vlastnostem. Vlastnost NodeName tedy bude obsahovat hodnotu #document, vlastnost NodeTypeString bude obsahovat hodnotu dokumentu a vlastnost URL bude obsahovat soubor: /// C: /DATA/DATA.xml value.
Vypořádání se s chybou
Zvláště zajímavé jsou vlastnosti související se zpracováním dokumentů při načítání. Například vlastnost ParseError vrací objekt XMLDOMParseError obsahující informace o chybě, ke které došlo při zpracování dokumentu.
Chcete-li napsat obslužnou rutinu chyb, můžete přidat následující kód:
Var XMLError: IXMLDOMParseError; ... XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); XMLError: = XMLDoc.ParseError; Pokud XMLError.ErrorCode<>0 Potom // // Zde zpracujeme chybu // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Nil;
Chcete-li zjistit, jaké informace jsou vráceny v případě chyby, změňte následující položku adresáře:
odstranění uzavíracího prvku
Nyní napíšeme kód, který vrátí hodnoty vlastností objektu XMLDOMParseError:
XMLError: = XMLDoc.ParseError; Pokud XMLError.ErrorCode<>0 Potom s XMLError Memo1.Lines začnou Add (‚Soubor:‘ + URL); Přidat (‚Kód:‘ + IntToStr (Kód chyby)); Přidat (‚Chyba:‘ + Důvod); Přidat (‚Text:‘ + SrcText); Přidat (‚Řádek:‘ + IntToStr (Řádek)); Přidat (‚Position:‘ + IntToStr (LinePos)); end Else Memo1.Lines.Add (XMLDoc.XML); Konec;
a spusťte naši aplikaci. V důsledku toho získáme následující informace o chybě.
Jak můžete vidět z výše uvedeného příkladu, informace vrácené objektem XMLDOMParseError jsou dostatečné k lokalizaci chyby a pochopení příčiny jejího výskytu.
Nyní obnovíme uzavírací prvek
Přístup ke stromu dokumentů
Chcete-li získat přístup ke stromu dokumentů, můžete buď získat kořenový prvek a poté iterovat jeho podřízené větve, nebo najít konkrétní větev. V prvním případě získáváme kořenový element prostřednictvím vlastnosti DocumentElement, která vrací objekt typu XMLDOMNode. Zde je návod, jak použít vlastnost DocumentElement k získání obsahu každého podřízeného prvku:
Var Node: IXMLDOMNode; Kořen: IXMLDOMElement; I: celé číslo; ... Kořen: = XMLDoc.DocumentElement; Pro I: = 0 až Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; Memo1.Lines.Add (Node.Text); Konec;
Pro náš dokument XML získáme následující text.
Pokud nás zajímá konkrétní větev nebo větev pod první podřízenou větví, můžeme použít buď metodu NodeFromID nebo metodu GetElementByTagName objektu XMLDOMDocument.
Metoda NodeFromID vyžaduje jedinečný identifikátor definovaný v XML Schema nebo Document Type Definition (DTD) a vrací větev s tímto identifikátorem.
Metoda GetElementByTagName vyžaduje řetězec s konkrétním prvkem (tag) a vrací všechny větve s tímto prvkem. Zde je návod, jak použít tuto metodu k nalezení všech umělců v našem adresáři CD-ROM:
Uzly: IXMLDOMNodeList; Uzel: IXMLDOMNode; ... Nodes: = XMLDoc.GetElementsByTagName (‚ARTIST‘); Pro I: = 0 až Nodes.Length-1 do Begin Node: = Nodes.Item [I]; Memo1.Lines.Add (Node.Text); Konec;
Pro náš dokument XML získáme následující text
Všimněte si, že metoda SelectNodes objektu XMLDOMNode poskytuje flexibilnější způsob přístupu k větvím dokumentu. Ale o tom více níže.
Větev dokumentu - Objekt XMLDOMNode
Objekt XMLDOMNode představuje větev dokumentu. S tímto objektem jsme se již setkali, když jsme získali kořenový prvek dokumentu:
Kořen: = XMLDoc.DocumentElement;
Chcete-li získat informace o větvi dokumentu XML, můžete použít vlastnosti objektu XMLDOMNode (tabulka 1).
Pro přístup k datům uloženým ve větvi se běžně používá buď vlastnost NodeValue (dostupná pro atributy, textové větve, komentáře, instrukce pro zpracování a sekce CDATA), nebo vlastnost Text, která vrací textový obsah větve, nebo vlastnost NodeTypedValue. Ten však lze použít pouze pro pobočky s napsanými položkami.
Procházení stromu dokumentů
Objekt XMLDOMNode poskytuje mnoho způsobů, jak procházet strom dokumentu. Například pro přístup k nadřazené větvi použijte vlastnost ParentNode (typ XMLDOMNode), přistupujte k podřízeným větvím prostřednictvím vlastností ChildNodes (typ XMLDOMNodeList), FirstChild a LastChild (typ XMLDOMNode) atd. Vlastnost OwnerDocument vrací objekt XMLDOMDocument, který identifikuje samotný dokument XML. Výše uvedené vlastnosti usnadňují navigaci ve stromu dokumentu.
Nyní projdeme všechny větve dokumentu XML:
Kořen: = XMLDoc.DocumentElement; Pro I: = 0 až Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; If Node.HasChildNodes Then GetChilds (Uzel, 0); Konec;
Jak bylo uvedeno výše, SelectNodes objektu XMLDOMNode poskytuje flexibilnější způsob přístupu k větvím dokumentu. Navíc existuje metoda SelectSingleNode, která vrací pouze první větev dokumentu. Obě tyto metody umožňují definovat šablony XSL pro vyhledávání větví.
Podívejme se na proces použití metody SelectNodes k načtení všech větví, které mají větev CD a dílčí větev PRICE:
Kořen: = XMLDoc.DocumentElement; Nodes: = Root.SelectNodes (‚CD / CENA‘);
Všechny dílčí větve PRICE větve CD budou umístěny do kolekce Nodes. K diskusi o šablonách XSL se vrátíme o něco později.
Manipulace s dětskými ratolestmi
Pro manipulaci s podřízenými větvemi můžeme použít metody objektu XMLDOMNode (tabulka 2).
Chcete-li zcela odstranit záznam o prvním disku, musíte spustit následující kód:
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // Získání kořenového prvku Root: = XMLDoc.DocumentElement; Uzel: = Kořen; // Odebere první podřízenou větev Node.RemoveChild (Node.FirstChild);
Všimněte si, že v tomto příkladu odstraňujeme první podřízenou větev. Jak odstranit první prvek první podřízené větve je znázorněno níže:
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // Získání kořenového prvku Root: = XMLDoc.DocumentElement; // a první podřízená větev Uzel: = Root.FirstChild; // Odebere první podřízenou větev Node.RemoveChild (Node.FirstChild);
Ve výše uvedeném příkladu jsme neodstranili první větev
Nyní přidáme novou větev. Níže je uveden kód, který ukazuje, jak přidat nový záznam hudebního disku CD-ROM:
Var NewNode: IXMLDOMNode; Podřízený: IXMLDOMNode; ... // Vytvořit novou větev -
Výše uvedený kód ukazuje následující sekvenci kroků pro přidání nové větve:
- Vytvoření nové větve pomocí metody CreateNode:
- vytvoření prvku pomocí metody CreateNode;
- přidání prvku do větve pomocí metody AppendChild;
- nastavení hodnoty prvku pomocí vlastnosti Text;
- … Opakujte pro všechny prvky.
- Přidání nové větve do dokumentu pomocí metody AppendChild.
Připomeňme, že metoda AppendChild přidá větev na konec stromu. Chcete-li přidat větev na konkrétní místo ve stromu, musíte použít metodu InsertBefore.
Sada větví - objekt XMLDOMNodeList
Objekt XMLNodeList obsahuje seznam větví, které lze sestavit pomocí metod SelectNodes nebo GetElementsByTagName a také získat z vlastnosti ChildNodes.
Použití tohoto objektu jsme již probrali v příkladu uvedeném v části „Navigace ve stromu dokumentů“. Zde uvedeme několik teoretických komentářů.
Počet větví v seznamu lze získat jako hodnotu vlastnosti Délka. Větve jsou indexovány od 0 do Délka-1 a každá jednotlivá větev je přístupná prostřednictvím odpovídající indexované položky v poli Item.
Procházení seznamu větví lze také provést pomocí metody NextNode, která vrátí další větev v seznamu nebo Nil, pokud je aktuální větev poslední. Chcete-li se vrátit na začátek seznamu, zavolejte metodu Reset.
Vytvářejte a ukládejte dokumenty
Probrali jsme tedy, jak můžete přidat větve a prvky do existujících dokumentů XML. Nyní vytvoříme dokument XML za běhu. V první řadě si pamatujte, že dokument lze načíst nejen z adresy URL, ale také z běžného řetězce. Zde je návod, jak vytvořit kořenový prvek, který pak lze použít k dynamickému sestavení zbytku prvků (které jsme již probrali v sekci Manipulace podřízených větví):
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; S: WideString; ... S: = '
Po vytvoření dokumentu XML jej uložte do souboru pomocí metody Save. Například:
XMLDoc.Save ('C: \ DATA \ NEWCD.XML');
Kromě uložení do souboru vám metoda Save umožňuje uložit dokument XML do nového objektu XMLDOMDocument. V tomto případě je dokument plně zpracován a v důsledku toho je zkontrolována jeho struktura a syntaxe. Zde je návod, jak uložit dokument do jiného objektu:
Procedure TForm1.Button2Click (Sender: TObject); var XMLDoc2: IXMLDOMDocument; begin XMLDoc2: = CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: = Nil; konec;
Závěrem, metoda Save také umožňuje uložit dokument XML do jiných objektů COM, které podporují rozhraní IStream, IPersistStream nebo IPersistStreamInit.
Použití šablon XSL
Když jsme probírali metodu SelectNodes objektu XMLDOMNode, zmínili jsme se, že poskytuje flexibilnější způsob přístupu k větvím dokumentu. Flexibilita spočívá v tom, že jako kritéria pro výběr větví můžete zadat šablonu XSL. Tyto šablony poskytují výkonný mechanismus pro vyhledávání informací v dokumentech XML. Chcete-li například získat seznam všech titulů hudebních CD-ROM v našem adresáři, můžete spustit následující dotaz:
Chcete-li zjistit, které disky umělců jsou vydány v USA, je požadavek vytvořen následovně:
Nodes: = Root.SelectNodes (‚CD / ARTIST‘);
Zde je návod, jak najít první jednotku v adresáři:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
A poslední:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
Chcete-li najít disky Boba Dylana, můžete spustit následující dotaz:
Nodes: = Root.SelectNodes (‘CD [$ any $ ARTIST =” Bob Dylan ”] / TITLE’);
a abychom získali seznam disků vyrobených po roce 1985, spustíme následující dotaz:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
Podrobnější popis syntaxe XSL vyžaduje samostatnou publikaci. Abych čtenáře zaujal a povzbudil k dalšímu výzkumu, uvedu jen jeden malý příklad možného použití XSL. Řekněme, že potřebujeme převést náš katalog na běžnou HTML tabulku. Pomocí tradičních metod musíme iterovat přes všechny větve stromu a pro každý přijatý prvek vytvořit odpovídající tagy
Pomocí XSL jednoduše vytvoříme šablonu (nebo šablonu stylů), která specifikuje, co a jak transformovat. Poté tuto šablonu překryjeme v našem katalogu – a máte hotovo: máme text šablony XSL, která převede katalog na tabulku (Výpis 2).
Kód pro překrytí šablony XSL v našem adresáři vypadá takto:
Procedure TForm1.Button2Click (Sender: TObject); var XSLDoc: IXMLDOMDocument; begin XSLDoc: = CoDOMDocument.Create; XSLDoc.Load (‘C: \ DATA \ DATA.xsl‘); Memo2.Text: = XMLDoc.TransformNode (XSLDoc); XSLDoc: = nula; konec;
Na závěr naší diskuse o XSL je třeba říci, že v současné době se tento jazyk aktivně používá pro transformaci mezi různými dokumenty XML a také pro formátování dokumentů.
Závěr
Z pochopitelných důvodů není možné pokrýt všechny objekty Microsoft XML DOM a uvést příklady jejich použití v jednom článku. Zde jsme se právě dotkli základních otázek používání XML DOM v aplikacích. Stůl 3 ukazuje všechny objekty implementované v Microsoft XML DOM.
ComputerPress 12 "2000
XML se stále více používá k ukládání informací a jejich výměně mezi aplikacemi a webovými stránkami. Mnoho aplikací používá tento jazyk jako základní jazyk pro ukládání dat, zatímco jiné jej používají pro export a import dat XML. Je tedy čas, aby vývojáři začali přemýšlet o tom, jak lze data XML použít v jejich vlastních aplikacích.
V tomto článku se podíváme na XML Document Object Model (DOM) a implementaci XML DOM od společnosti Microsoft.
XML DOM je objektový model, který poskytuje vývojářům objekty pro načítání a zpracování souborů XML. Objektový model se skládá z následujících základních objektů: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap a XMLDOMParseError. Každý z těchto objektů (kromě XMLDOMParseError) obsahuje vlastnosti a metody, které vám umožňují získat informace o objektu, manipulovat s hodnotami a strukturou objektu a procházet strukturou dokumentu XML.
Podívejme se na hlavní objekty XML DOM a ukažme si některé příklady jejich použití v Borland Delphi.
Použití XML DOM v Borland Delphi
Abyste mohli používat Microsoft XML DOM v aplikacích Delphi, musíte k projektu připojit příslušnou knihovnu typů. K tomu spustíme příkaz Projekt | Import knihovny typů a v dialogovém okně Import knihovny typů vyberte knihovnu Microsoft XML verze 2.0 (verze 2.0), která se obvykle nachází v souboru Windows \ System \ MSXML.DLL.
Po kliknutí na tlačítko Create Unit se vytvoří modul rozhraní MSXML_TLB, který nám umožní používat objekty XML DOM: DOMDocument, XMLDocument, XMLHTTPRequest a řadu dalších, implementovaných v knihovně MSXML.DLL. Odkaz na modul MSXML_TLB musí být v seznamu Použití.
XML DOM zařízení
Objektový model dokumentu představuje dokument XML ve stromové struktuře větví. XML DOM API umožňují aplikacím procházet strom dokumentů a manipulovat s jeho větvemi. Každá větev může mít specifický typ (DOMNodeType), podle kterého se určuje nadřazená a podřízená větev. Většina dokumentů XML obsahuje větve typu element, atribut a text. Atributy jsou speciálním druhem větvení a nejsou podřízenými větvemi. K manipulaci s atributy se používají speciální metody poskytované objekty XML DOM.
Kromě implementace rozhraní doporučených konsorciem World Wide Web Consortium (W3C), Microsoft XML DOM obsahuje metody, které podporují XSL, XSL vzory, jmenné prostory a datové typy. Například metoda SelectNodes umožňuje použít syntaxi vzoru XSL k nalezení větví v určitém kontextu a metoda TransformNode podporuje použití XSL k provádění transformací.
Test XML dokumentu
Jako příklad dokumentu XML si vezměme adresář hudebního CD-ROM, který má následující strukturu:
Nyní jsme připraveni začít zkoumat objektový model XML DOM, počínaje objektem XMLDOMDocument.
Dokument XML - Objekt XMLDOMDocument
Práce s dokumentem XML začíná jeho načtením. K tomu používáme metodu Load, která má pouze jeden parametr, který určuje URL načítaného dokumentu. Při načítání souborů z lokálního disku se zadává pouze celý název souboru (soubor: /// protokol lze v tomto případě vynechat). Pokud je dokument XML uložen jako řetězec, použijte k načtení dokumentu metodu LoadXML.
Vlastnost Async se používá k řízení způsobu načítání dokumentu (synchronního nebo asynchronního). Ve výchozím nastavení je tato vlastnost nastavena na hodnotu True, což znamená, že dokument je načten asynchronně a řízení je vráceno aplikaci před úplným načtením dokumentu. V opačném případě se dokument načte synchronně a pak musíte zkontrolovat hodnotu vlastnosti ReadyState, abyste zjistili, zda se dokument načetl nebo ne. Můžete také vytvořit obslužnou rutinu pro událost OnReadyStateChange, která převezme řízení, když se změní hodnota vlastnosti ReadyState.
Následující text ukazuje, jak načíst dokument XML pomocí metody Load:
Používá ... MSXML_TLB ... procedure TForm1.Button1Click (Sender: TObject); var XMLDoc: IXMLDOMDocument; begin XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // // Zde se nachází kód, který // manipuluje s dokumentem XML a jeho větvemi // XMLDoc: = Nil; konec;
Po načtení dokumentu máme přístup k jeho vlastnostem. Vlastnost NodeName tedy bude obsahovat hodnotu #document, vlastnost NodeTypeString bude obsahovat hodnotu dokumentu a vlastnost URL bude obsahovat soubor: /// C: /DATA/DATA.xml value.
Vypořádání se s chybou
Zvláště zajímavé jsou vlastnosti související se zpracováním dokumentů při načítání. Například vlastnost ParseError vrací objekt XMLDOMParseError obsahující informace o chybě, ke které došlo při zpracování dokumentu.
Chcete-li napsat obslužnou rutinu chyb, můžete přidat následující kód:
Var XMLError: IXMLDOMParseError; ... XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); XMLError: = XMLDoc.ParseError; Pokud XMLError.ErrorCode<>0 Potom // // Zde zpracujeme chybu // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: = Nil;
Chcete-li zjistit, jaké informace jsou vráceny v případě chyby, změňte následující položku adresáře:
odstranění uzavíracího prvku
Nyní napíšeme kód, který vrátí hodnoty vlastností objektu XMLDOMParseError:
XMLError: = XMLDoc.ParseError; Pokud XMLError.ErrorCode<>0 Potom s XMLError Memo1.Lines začnou Add (‚Soubor:‘ + URL); Přidat (‚Kód:‘ + IntToStr (Kód chyby)); Přidat (‚Chyba:‘ + Důvod); Přidat (‚Text:‘ + SrcText); Přidat (‚Řádek:‘ + IntToStr (Řádek)); Přidat (‚Position:‘ + IntToStr (LinePos)); end Else Memo1.Lines.Add (XMLDoc.XML); Konec;
a spusťte naši aplikaci. V důsledku toho získáme následující informace o chybě.
Jak můžete vidět z výše uvedeného příkladu, informace vrácené objektem XMLDOMParseError jsou dostatečné k lokalizaci chyby a pochopení příčiny jejího výskytu.
Nyní obnovíme uzavírací prvek
Přístup ke stromu dokumentů
Chcete-li získat přístup ke stromu dokumentů, můžete buď získat kořenový prvek a poté iterovat jeho podřízené větve, nebo najít konkrétní větev. V prvním případě získáváme kořenový element prostřednictvím vlastnosti DocumentElement, která vrací objekt typu XMLDOMNode. Zde je návod, jak použít vlastnost DocumentElement k získání obsahu každého podřízeného prvku:
Var Node: IXMLDOMNode; Kořen: IXMLDOMElement; I: celé číslo; ... Kořen: = XMLDoc.DocumentElement; Pro I: = 0 až Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; Memo1.Lines.Add (Node.Text); Konec;
Pro náš dokument XML získáme následující text.
Pokud nás zajímá konkrétní větev nebo větev pod první podřízenou větví, můžeme použít buď metodu NodeFromID nebo metodu GetElementByTagName objektu XMLDOMDocument.
Metoda NodeFromID vyžaduje jedinečný identifikátor definovaný v XML Schema nebo Document Type Definition (DTD) a vrací větev s tímto identifikátorem.
Metoda GetElementByTagName vyžaduje řetězec s konkrétním prvkem (tag) a vrací všechny větve s tímto prvkem. Zde je návod, jak použít tuto metodu k nalezení všech umělců v našem adresáři CD-ROM:
Uzly: IXMLDOMNodeList; Uzel: IXMLDOMNode; ... Nodes: = XMLDoc.GetElementsByTagName (‚ARTIST‘); Pro I: = 0 až Nodes.Length-1 do Begin Node: = Nodes.Item [I]; Memo1.Lines.Add (Node.Text); Konec;
Pro náš dokument XML získáme následující text
Všimněte si, že metoda SelectNodes objektu XMLDOMNode poskytuje flexibilnější způsob přístupu k větvím dokumentu. Ale o tom více níže.
Větev dokumentu - Objekt XMLDOMNode
Objekt XMLDOMNode představuje větev dokumentu. S tímto objektem jsme se již setkali, když jsme získali kořenový prvek dokumentu:
Kořen: = XMLDoc.DocumentElement;
Chcete-li získat informace o větvi dokumentu XML, můžete použít vlastnosti objektu XMLDOMNode (tabulka 1).
Pro přístup k datům uloženým ve větvi se běžně používá buď vlastnost NodeValue (dostupná pro atributy, textové větve, komentáře, instrukce pro zpracování a sekce CDATA), nebo vlastnost Text, která vrací textový obsah větve, nebo vlastnost NodeTypedValue. Ten však lze použít pouze pro pobočky s napsanými položkami.
Procházení stromu dokumentů
Objekt XMLDOMNode poskytuje mnoho způsobů, jak procházet strom dokumentu. Například pro přístup k nadřazené větvi použijte vlastnost ParentNode (typ XMLDOMNode), přistupujte k podřízeným větvím prostřednictvím vlastností ChildNodes (typ XMLDOMNodeList), FirstChild a LastChild (typ XMLDOMNode) atd. Vlastnost OwnerDocument vrací objekt XMLDOMDocument, který identifikuje samotný dokument XML. Výše uvedené vlastnosti usnadňují navigaci ve stromu dokumentu.
Nyní projdeme všechny větve dokumentu XML:
Kořen: = XMLDoc.DocumentElement; Pro I: = 0 až Root.ChildNodes.Length-1 do Begin Node: = Root.ChildNodes.Item [I]; If Node.HasChildNodes Then GetChilds (Uzel, 0); Konec;
Jak bylo uvedeno výše, SelectNodes objektu XMLDOMNode poskytuje flexibilnější způsob přístupu k větvím dokumentu. Navíc existuje metoda SelectSingleNode, která vrací pouze první větev dokumentu. Obě tyto metody umožňují definovat šablony XSL pro vyhledávání větví.
Podívejme se na proces použití metody SelectNodes k načtení všech větví, které mají větev CD a dílčí větev PRICE:
Kořen: = XMLDoc.DocumentElement; Nodes: = Root.SelectNodes (‚CD / CENA‘);
Všechny dílčí větve PRICE větve CD budou umístěny do kolekce Nodes. K diskusi o šablonách XSL se vrátíme o něco později.
Manipulace s dětskými ratolestmi
Pro manipulaci s podřízenými větvemi můžeme použít metody objektu XMLDOMNode (tabulka 2).
Chcete-li zcela odstranit záznam o prvním disku, musíte spustit následující kód:
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // Získání kořenového prvku Root: = XMLDoc.DocumentElement; Uzel: = Kořen; // Odebere první podřízenou větev Node.RemoveChild (Node.FirstChild);
Všimněte si, že v tomto příkladu odstraňujeme první podřízenou větev. Jak odstranit první prvek první podřízené větve je znázorněno níže:
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; XMLDoc: = CoDOMDocument.Create; XMLDoc.Async: = False; XMLDoc.Load (‘C: \ DATA \ DATA.xml‘); // Získání kořenového prvku Root: = XMLDoc.DocumentElement; // a první podřízená větev Uzel: = Root.FirstChild; // Odebere první podřízenou větev Node.RemoveChild (Node.FirstChild);
Ve výše uvedeném příkladu jsme neodstranili první větev
Nyní přidáme novou větev. Níže je uveden kód, který ukazuje, jak přidat nový záznam hudebního disku CD-ROM:
Var NewNode: IXMLDOMNode; Podřízený: IXMLDOMNode; ... // Vytvořit novou větev -
Výše uvedený kód ukazuje následující sekvenci kroků pro přidání nové větve:
- Vytvoření nové větve pomocí metody CreateNode:
- vytvoření prvku pomocí metody CreateNode;
- přidání prvku do větve pomocí metody AppendChild;
- nastavení hodnoty prvku pomocí vlastnosti Text;
- … Opakujte pro všechny prvky.
- Přidání nové větve do dokumentu pomocí metody AppendChild.
Připomeňme, že metoda AppendChild přidá větev na konec stromu. Chcete-li přidat větev na konkrétní místo ve stromu, musíte použít metodu InsertBefore.
Sada větví - objekt XMLDOMNodeList
Objekt XMLNodeList obsahuje seznam větví, které lze sestavit pomocí metod SelectNodes nebo GetElementsByTagName a také získat z vlastnosti ChildNodes.
Použití tohoto objektu jsme již probrali v příkladu uvedeném v části „Navigace ve stromu dokumentů“. Zde uvedeme několik teoretických komentářů.
Počet větví v seznamu lze získat jako hodnotu vlastnosti Délka. Větve jsou indexovány od 0 do Délka-1 a každá jednotlivá větev je přístupná prostřednictvím odpovídající indexované položky v poli Item.
Procházení seznamu větví lze také provést pomocí metody NextNode, která vrátí další větev v seznamu nebo Nil, pokud je aktuální větev poslední. Chcete-li se vrátit na začátek seznamu, zavolejte metodu Reset.
Vytvářejte a ukládejte dokumenty
Probrali jsme tedy, jak můžete přidat větve a prvky do existujících dokumentů XML. Nyní vytvoříme dokument XML za běhu. V první řadě si pamatujte, že dokument lze načíst nejen z adresy URL, ale také z běžného řetězce. Zde je návod, jak vytvořit kořenový prvek, který pak lze použít k dynamickému sestavení zbytku prvků (které jsme již probrali v sekci Manipulace podřízených větví):
Var XMLDoc: IXMLDOMDocument; Kořen: IXMLDOMNode; Uzel: IXMLDOMNode; S: WideString; ... S: = '
Po vytvoření dokumentu XML jej uložte do souboru pomocí metody Save. Například:
XMLDoc.Save ('C: \ DATA \ NEWCD.XML');
Kromě uložení do souboru vám metoda Save umožňuje uložit dokument XML do nového objektu XMLDOMDocument. V tomto případě je dokument plně zpracován a v důsledku toho je zkontrolována jeho struktura a syntaxe. Zde je návod, jak uložit dokument do jiného objektu:
Procedure TForm1.Button2Click (Sender: TObject); var XMLDoc2: IXMLDOMDocument; begin XMLDoc2: = CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: = Nil; konec;
Závěrem, metoda Save také umožňuje uložit dokument XML do jiných objektů COM, které podporují rozhraní IStream, IPersistStream nebo IPersistStreamInit.
Použití šablon XSL
Když jsme probírali metodu SelectNodes objektu XMLDOMNode, zmínili jsme se, že poskytuje flexibilnější způsob přístupu k větvím dokumentu. Flexibilita spočívá v tom, že jako kritéria pro výběr větví můžete zadat šablonu XSL. Tyto šablony poskytují výkonný mechanismus pro vyhledávání informací v dokumentech XML. Chcete-li například získat seznam všech titulů hudebních CD-ROM v našem adresáři, můžete spustit následující dotaz:
Chcete-li zjistit, které disky umělců jsou vydány v USA, je požadavek vytvořen následovně:
Nodes: = Root.SelectNodes (‚CD / ARTIST‘);
Zde je návod, jak najít první jednotku v adresáři:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
A poslední:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
Chcete-li najít disky Boba Dylana, můžete spustit následující dotaz:
Nodes: = Root.SelectNodes (‘CD [$ any $ ARTIST =” Bob Dylan ”] / TITLE’);
a abychom získali seznam disků vyrobených po roce 1985, spustíme následující dotaz:
Nodes: = Root.SelectNodes (‚CD / TITLE‘);
Podrobnější popis syntaxe XSL vyžaduje samostatnou publikaci. Abych čtenáře zaujal a povzbudil k dalšímu výzkumu, uvedu jen jeden malý příklad možného použití XSL. Řekněme, že potřebujeme převést náš katalog na běžnou HTML tabulku. Pomocí tradičních metod musíme iterovat přes všechny větve stromu a pro každý přijatý prvek vytvořit odpovídající tagy
Pomocí XSL jednoduše vytvoříme šablonu (nebo šablonu stylů), která specifikuje, co a jak transformovat. Poté tuto šablonu překryjeme v našem katalogu – a máte hotovo: máme text šablony XSL, která převede katalog na tabulku (Výpis 2).
Kód pro překrytí šablony XSL v našem adresáři vypadá takto:
Procedure TForm1.Button2Click (Sender: TObject); var XSLDoc: IXMLDOMDocument; begin XSLDoc: = CoDOMDocument.Create; XSLDoc.Load (‘C: \ DATA \ DATA.xsl‘); Memo2.Text: = XMLDoc.TransformNode (XSLDoc); XSLDoc: = nula; konec;
Na závěr naší diskuse o XSL je třeba říci, že v současné době se tento jazyk aktivně používá pro transformaci mezi různými dokumenty XML a také pro formátování dokumentů.
Závěr
Z pochopitelných důvodů není možné pokrýt všechny objekty Microsoft XML DOM a uvést příklady jejich použití v jednom článku. Zde jsme se právě dotkli základních otázek používání XML DOM v aplikacích. Stůl 3 ukazuje všechny objekty implementované v Microsoft XML DOM.
ComputerPress 12 "2000
Všechny vítám! Několik let jsem psal v Matlabu a pak jsem byl netrpělivý, abych napsal program v Delphi.
Potřebuji se naučit pracovat s xml dokumenty. Pracuji ve společnosti RAD Stiduo XE3. Existuje komponenta TXMLDocument, pravděpodobně známá mnoha programátorům Delphi. Zdá se, že toho dokáže hodně. Problém je ale v tom, že k tomu neexistuje jasná dokumentace a popis. Pomoc v RAD Studiu je svinstvo, protože tam nejsou žádné normální informace; pouze roztroušeně po stránkách skrovné nápovědy k některým metodám a postupům (žádné příklady a normální popis). Prohrabaný celým internetem. Nalezená pouze témata na fórech s řešením konkrétních problémů, kde musíte další hodinu hádat, co dělá ten či onen řádek spojený s přístupem k xml souboru.
Dále potřebuji manuál o hlavních funkcích, postupech a metodách používaných při práci s xml. Učebnice, manuál, popis. Nebo alespoň "xml v Delphi pro figuríny". Například:
Chcete-li otevřít soubor xml, použijte metodu XMLDocument1.LoadFromFile ("filemane.xml"), kde název_souboru je název souboru.
Proměnná nodelist typu IXMLNode slouží k uložení seznamu potomků. K definování tohoto seznamu se používá metoda Xmldocument1.DocumentElement (kde XMLDocument1 je soubor xml, který má být zkoumán).
K dotazu na obsah podřízeného prvku "element1" použijte metodu XMLDocument1.DocumentElement.ChildNodes ["element1"].
a v tomto duchu dále na všechny aplikované metody, postupy, datové typy.
Kde najdu podobné návody/popisy? Kdo může pomoci?
Pokud potřebujete konkrétní úkol, popíšu ho.
Existuje xml dokument formuláře:
Nějaký text
Nějaký text chyby
Jiný text chyby
V kódu programu máme:
var
...
rodič, potomek1: IXMLNode;
začít
XMLDocument1.LoadFromFile ("f: \ název_souboru.x ml");
XMLDocument1.Active: = true;
.
.
konec
Co se musíte naučit dělat:
(předem se omlouvám, pokud nesprávně pojmenuji součásti xml dokumentu)
1. Získejte jméno kořenového prvku (v našem případě ltm) a také seznam jeho atributů (verze, typ) a jejich hodnot ("1.0", "nastavení").
2. Získejte počet prvků, které jsou potomky kořene. V tomto případě je jich 7: templateFiles, dimenze, hotspot, hotspot, data, data, data. Získejte názvy prvků (tagů) (templateFiles, dimenze atd.). Poté, co získám počet prvků a naučím se, jak extrahovat jejich jména, budu opakovat od 0 do počtu-1 a udělám, co potřebuji.
3. Získejte číslo a seznam atributů požadovaného prvku. Například pro prvek hotspot. Správná odpověď by byla 4 atributy. U prvního aktivního prvku to budou jméno, styl, scéna, ath. Pro druhý - stejný, jen místo atributu ath - atribut rz.
Všimněte si, že v souboru jsou 2 prvky aktivního bodu s různými atributy. Zde je návod, jak s nimi pracovat (pokud existuje více než 1 prvek stejného názvu)?
Chci takto: Dostanu seznam dětí podle rel. ke kořenovému (viz str. 2), proveďte přes ně smyčku for a najděte prvky aktivního bodu, ve kterých se parametr name rovná požadovanému (řekněme "hs015_2" - jeden takový prvek určitě bude). Je možné nějak vyřešit tento problém bez smyčky? To znamená, získat hodnotu atributu scény pro prvek hotspot s názvem = "hs015_2"?
4. Výše uvedené proveďte pro uzly a prvky, které jsou ve vztahu k dětem děti. V mém příkladu uzel (potomek a rodič a.
Pokud tomu dobře rozumím, musíte nějak přenést obsah uzlu do variabilní jako IXMLNode a proveďte totéž jako v položkách 1-3. Tak?
5. Musíte se naučit, jak změnit výše uvedené parametry (nastavit si vlastní).
Zdá se to zatím. V této fázi jsou pro mě nejdůležitější syntaktické konstrukce.
Kdo vlastní toto téma, napište prosím další syntaktické konstrukce k vyřešení výše uvedených problémů (jak získat atributy, jejich počet, počet prvků, jejich názvy atd.). Hlavní věcí je nyní zvládnout syntaxi a svůj algoritmus implementuji později. Předem moc děkuji!
P.S. Opravdu bych nechtěl psát svůj vlastní XML parser od začátku jen proto, že neexistuje žádný normální popis pro ty stávající.