DZWON

Są tacy, którzy czytają tę wiadomość przed tobą.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu

Dziś postanowiłem trochę kontynuować temat pracy z XML-RPC w WordPress. Jak to zwykle mi się zdarza, pomysł narodził się w momencie czytania przypadkowego bloga, postanowiłem przyjrzeć się pracy z wpisami na blogu i jednocześnie spróbować napisać coś na miarę moich potrzeb.

Oczywiście nie będę dzisiaj publikował programu, ale niektóre obliczenia, zestawienia i pomysły będą obecne w poście.

Krótko omówiłem pracę z XML-RPC w poście „” Dzisiaj postaramy się posunąć naprzód w naszej pracy i użyć kilku powiązanych ze sobą metod, aby uzyskać pewne informacje z bloga.

Konkretujemy cel na dziś: musisz uzyskać dane o postach na blogu za pomocą dostępnych metod z interfejsu API WordPress.

Aby osiągnąć ten cel, potrzebujemy następujących modułów Delphi: XMLIntf , xmldom , XMLDoc i biblioteki synapce lub komponent Indy idHTTP (do kogokolwiek, jak chcesz).

1. Testowanie połączenia z blogiem.

Uważam, że pierwszą rzeczą do zrobienia jest sprawdzenie, czy blog działa poprawnie pod kątem następujących możliwych błędów:

  1. Blog wyłączył możliwość korzystania z XML-RPC
  2. Użytkownik podał nieprawidłowe dane (adres URL, nazwę użytkownika lub hasło).

Aby sprawdzić możliwość pracy z XML-RPC na blogu, wystarczy skorzystać z metody demo.sayHello... Jeśli odpowiedź to linia "Dzień dobry", wszystko jest w porządku i możesz przejść do następnego kroku kontroli. Aby przeprowadzić tę kontrolę, musimy wykonać trzy proste zadania:

  • wygeneruj prawidłowy dokument XML
  • wyślij zapytanie do serwera i uzyskaj odpowiedź
  • przeanalizuj odpowiedź

Tworzymy dokument XML, który powinien wyglądać następująco:

demo.sayHello test

W tym celu użyjemy interfejsu IXMLDocument:

[...] var doc: IXMLDocument; // dokument Root: IXMLNode; // węzeł główny początek dziedziczony Create; doc: \u003d NewXMLDocument (); // utwórz pusty dokument Root: \u003d Doc. CreateElement ("methodCall", ""); // dodaj węzeł główny Doc. DocumentElement: \u003d Root; Korzeń. AddChild („nazwaMetody”). NodeValue: \u003d "demo.sayHello"; // dodaj nazwę metody Korzeń. AddChild („params”). AddChild („param”). AddChild („wartość”). AddChild („ciąg”). NodeValue: \u003d "test"; // zapis parametrów metody [ ... ]

Ponieważ sam dokument XML jest dość prosty, pozwoliłem sobie na lekkie „zamrożenie” i przy ostatniej linijce kodu zapisałem jednocześnie wszystkie węzły i wartość jedynego parametru naszej metody.
Teraz możesz wysłać dokument na serwer i otrzymać odpowiedź:

[...] z THTTPSend. Utwórz, aby rozpocząć Doc. SaveToStream (dokument); // zapisz dokument do treści żądania jeśli HTTPMethod ("POST", aURL) to zacznij // żądanie zostało pomyślnie wysłane i otrzymało odpowiedź koniec, jeszcze początek // żądanie nie powiodło się koniec; koniec; […]

Co mi się podoba Synapcejest to więc to, że niepotrzebne „ruchy ciała” nie są wymagane przy wypełnianiu nagłówków Długość treści, Typ zawartości i tak dalej. Oczywiście nikt nie zadaje sobie trudu, aby samemu wypełnić wszystkie możliwe nagłówki, ale można to zrobić tak, jak pokazałem powyżej - wszystko odbywa się automatycznie.
Przechodząc dalej, analizując odpowiedź.
Przypomnę ci to pomyślne wysłanie żądania do serwera nie oznacza, że \u200b\u200bpomyślnie uzyskaliśmy dostęp do XML-RPC bloga. Pomyślne wysłanie żądania oznacza tylko, że wysłaliśmy żądanie i otrzymaliśmy odpowiedź, ale nie wiemy, co jest w odpowiedzi, czy nie..
Aby na razie nie zawracać sobie głowy niepotrzebnymi metodami i metodami parsowania odpowiedzi z serwera, proponuję w tym przypadku zatrzymać się na prostym sprawdzeniu:

[...] Dok. LoadFromStream (Document, xetUTF_8); // napisał dokument XML jeśli Doc. DocumentElement. ChildNodes. FindNode ("fault") \u003d nil, a następnie ShowMessage ( „XML-RPC działa prawidłowo”) [ ... ]

Zgodnie ze specyfikacją XML-RPC komunikaty o błędach są zawarte w węźle o nazwie fault. Dlatego w naszym przypadku wystarczy sprawdzić obecność takiego węzła w dokumencie XML odpowiedzi - jeśli go nie ma, to weryfikacja przebiegła pomyślnie, wygenerowano poprawne żądanie i XML-RPC działa poprawnie.
Przechodząc do następnego kroku - sprawdzenie poprawności danych podanych przez użytkownika i możliwości pracy użytkownika z blogiem XML-RPC.
Tylko administrator może pracować z XML-RPC bloga, dlatego konieczne jest, aby dowiedzieć się, kto próbuje uzyskać dostęp. W tym celu używamy metody wp.getUsersBlogs... Parametry metody to login i hasło.
Zanim jednak zaczniemy wysyłać zapytanie i otrzymywać odpowiedź, myślę, że warto pomyśleć trochę o przyszłości i zadbać o pracę z błędami, generowanie dokumentów itp.
W poprzednim sprawdzeniu, można by rzec, było rozpieszczanie - najprostsza wersja dzieła typu:
wysłane / odebrane / here_zhe_disassembled / zapomniałem / poszedłem dalej.
Ponieważ planuję w przyszłości rozwinąć moduł do pracy z WordPress API, warto zdecydować się na następujące punkty w pracy:

  1. Tworzą „szkielet” dokumentu
  2. Zapisz wszystkie niezbędne parametry w dokumencie, biorąc pod uwagę typy danych
  3. Wyślij żądanie i odbierz odpowiedź z serwera
  4. Przeanalizuj odpowiedź i, jeśli odpowiedź zawiera komunikat o błędzie, przeczytaj ją poprawnie

Wszystkie te cztery kroki wykonałem jako oddzielne metody klasowe. Przez „szkielet” dokumentu rozumiem następującą treść:

MethodName

To znaczy część dokumentu zawierająca nazwę metody i węzeł params brak zawartości. Ponadto pozostaje tylko poprawnie wypełnić listę parametrów. Co teraz zrobimy.

W sumie XML-RPC umożliwia korzystanie z sześciu prostych typów danych:

  1. int i i4 to liczby całkowite)
  2. liczby podwójnie ułamkowe
  3. string - stringi
  4. base64 - zakodowany ciąg
  5. dateTime.iso8601 - data / godzina
  6. boolean

Rozpoczynamy nowy typ danych:

TSimpleType \u003d (tsInt, tsI4, tsString, tsDouble, tsDateTime, tsBase64, tsBoolean);

Korzystając z wartości tego typu, zdefiniujemy tag dla wartości parametru.

Ponieważ operacje tworzenia „szkieletu” dokumentu i dodawania parametrów metody są oddzielone różnymi funkcjami, utworzymy kolejny pomocniczy typ danych:

PXMLDocument \u003d ^ IXMLDocument;

Teraz metoda dodawania parametru do samego dokumentu:

procedura TBlog. SetParam (SimpleType: TSimpleType; Wartość: ciąg; Dokument: PXMLDocument); var Root: IXMLNode; rozpocząć, jeśli Dokument ^. IsEmptyDoc, a następnie Exit; // dokument jest pusty Root: \u003d Dokument ^. DocumentElement. ChildNodes. FindNode ("parametry"); jeśli Root \u003d nil to Exit; // nie znaleziono węzła case SimpleType z tsInt: Root. AddChild („param”). AddChild („wartość”). AddChild („int”). NodeValue: \u003d wartość; tsI4: Root. AddChild („param”). AddChild („wartość”). AddChild („i4”). NodeValue: \u003d wartość; tsString: Root. AddChild („param”). AddChild („wartość”). AddChild („ciąg”). NodeValue: \u003d wartość; tsDouble: Root. AddChild („param”). AddChild („wartość”). AddChild („double”). NodeValue: \u003d wartość; tsDateTime: Root. AddChild („param”). AddChild („wartość”). AddChild ("dateTime.iso8601"). NodeValue: \u003d wartość; tsBase64: Root. AddChild („param”). AddChild („wartość”). AddChild („base64”). NodeValue: \u003d wartość; tsBoolean: Root. AddChild („param”). AddChild („wartość”). AddChild („boolean”). NodeValue: \u003d wartość; koniec; koniec;

Ta metoda działa tylko w przypadku rekordów typu prostego. Podczas pracy ze strukturami konieczne jest dopracowanie algorytmu.

Teraz o analizie komunikatów o błędach. Spójrzmy na przykład, jak wygląda komunikat o błędzie w XML-RPC:

kod błędu 403 faultString Zła kombinacja login / hasło.

Komunikat o błędzie dociera do nas w strukturze. Ponadto, jeśli założymy, że tags członeksą numerowane od zera, wtedy każdy parzysty element struktury jest kodem błędu, a nieparzysty to tekst błędu. Dlatego metoda obsługi komunikatów o błędach może wyglądać następująco:

funkcja TBlog. ParseErrors (aDocument: PXMLDocument): TStringList; var i: liczba całkowita; Lista: IDOMNodeList; kod: ciąg; lista początkowa: \u003d aDocument ^. DOMDocument. getElementsByTagName ("członek"); Wynik: \u003d TStringList. Stwórz; dla i: \u003d 0 do listy. length - 1 do początku case i mod 2 of 0: code: \u003d (List. item [i]. lastChild. firstChild as IDOMNodeEx). tekst; // element parzysty - przeczytaj kod błędu 1 : // element nieparzysty - przeczytaj tekst błędu i zapisz wynik Wynik. Dodaj (kod + "" + (Lista. Pozycja [i]. LastChild. FirstChild as IDOMNodeEx). Text); koniec; koniec; koniec;

Tutaj kod błędu i tekst są zapisywane do TStringList. Myślę, że w razie potrzeby możesz łatwo odczytać kod i tekst na różne listy lub tablice. Jeszcze tego nie potrzebujemy.

Rozważaliśmy już wysłanie dokumentu, więc od razu przedstawiam sposób sprawdzenia poprawności danych:

funkcja TBlog. CheckUserAccess (const aURL, aUser, aPassword: string; var Error: string): boolean; var Doc: IXMLDocument; begin Doc: \u003d GetDocument ("wp.getUsersBlogs"); // utworzył „szkielet” // dodaj parametry SetParam (tsString, aUser, @ Doc); SetParam (tsString, aPassword, @ Doc); SendQuery (@ Doc, aURL); // wyślij zapytanie jeśli nie Doc. IsEmptyDoc to // czy dokument został napisany poprawnie zacząć, jeśli Doc. DocumentElement. ChildNodes. FindNode ("fault") ‹› nil then // pojawia się komunikat o błędzie początek Wynik: \u003d false; Błąd: \u003d ParseErrors (@ Doc). Ciągi [0]; end else Wynik: \u003d true; end else Wynik: \u003d false; koniec;

Jeśli zostanie odebrany komunikat o błędzie, zapisz go w zmiennej Error. W tym przypadku struktura zawiera tylko jeden komunikat błędu - dlatego tak łatwo go napisałem:

Błąd: \u003d ParseErrors (@ Doc). Ciągi [0];

Tak więc przeprowadzono dwa sprawdzenia i ustaliliśmy, że XML-RPC jest włączony i działa poprawnie, a użytkownik wprowadził poprawne dane logowania i hasło oraz może pracować z WordPress API. Co dalej? A potem zaczynamy główną pracę - otrzymujemy dane z komentarzy na blogu.

2. Uzyskaj dane o postach na blogu.

Czym więc mamy do dyspozycji WordPress. Najpierw przejrzyjmy pokrótce metody z xmlrpc.php.

wp.getPostStatusList - wyświetla wartości statusu wiadomości. W rzeczywistości wynik będzie miał cztery wiersze: „wersja robocza”, „oczekujące”, „prywatne”, „publikacja”.

Chociaż ta metoda jest dla nas bezużyteczna.

blogger.getRecentPosts - Ta funkcja pochodzi już z interfejsu API Bloggera, ale jest obsługiwana w WordPress. Wynikiem będą najnowsze posty na blogu, w tym cała treść posta.

Możesz skorzystać z tej metody, ALE praca programu zostanie spowolniona, ponieważ będziesz musiał „przeciągnąć” cały wpis w sieci. A jeśli spróbujemy uzyskać pełną listę postów na blogu, to najwyraźniej musimy iść spać, nie czekając na wynik. Dlatego na razie odkładamy tę metodę na bok.

metaWeblog.getRecentPosts - podobny do poprzedniej metody.

mt.getRecentPostTitles - metoda z MovableType API. Sądząc po nazwie - czego potrzebujemy. Zobacz opis metody.

Metoda zwraca listę zawierającą tytuły postów na blogu. W takim przypadku treść nie jest zapisywana na liście.

Parametry wejściowe:

  • Ciąg znaków blogid
  • Nazwa użytkownika w postaci ciągu znaków
  • Hasło ciągowe
  • int numberOfPosts

blogid zawsze 1 (patrz opis w xmlrpc.php)

liczba postów - liczba stanowisk do wyświetlenia. Jeśli parametr ma wartość większą niż liczba postów na blogu, wówczas metoda zwraca listę wszystkich postów.

Pozostaje dowiedzieć się, jaka jest ta lista. A na wyjściu będziemy mieli tablicę struktur, która obejmuje:

  • data utworzenia pozycji
  • identyfikator użytkownika
  • postid
  • tytuł.

Wspaniale. Skorzystamy z tej metody, a jednocześnie nauczymy się analizować złożone struktury odpowiedzi.

Myślę, że nie warto pisać o tworzeniu wniosku. Procedura jest podobna do opisanej powyżej. Przyjrzyjmy się szczegółowo analizie odpowiedzi serwera. Poznaliśmy, jak wygląda typ struktury podczas analizowania odpowiedzi zawierającej błąd autoryzacji. Zobaczmy, czym jest tablica.

Tablice nie mają nazwy i są opisane tagiem ... Zawiera jedną pozycję i jedno lub więcej dzieci gdzie dane są ustawione. Dowolne inne typy w dowolnej kolejności, a także inne tablice, mogą działać jako elementy tablicy - co pozwala opisywać tablice wielowymiarowe. Możesz także opisać szereg struktur. Na przykład tablica czterech elementów wyglądałaby następująco:

34 Witaj świecie! 0 -34

Na naszym wyjściu z metody mt.getRecentPostTitles
będzie zawierać tablica struktur, a jedna struktura to informacja dla jednego posta na blogu. Dlatego czytanie danych z postów na blogu można z grubsza podzielić na następujące kroki:

  1. Wyodrębnij wszystkie elementy z dokumentu XML ... pierworodny. childNodes; // pobrano wszystkich członków dla 1 wartości dla j: \u003d 0 do członków. length - 1 zaczyna się od Result [i] do case j z 0: dateCreated: \u003d (Members [j]. lastChild. firstChild as IDOMNodeEx). tekst; 1: user_id: \u003d StrToInt ((Members [j]. LastChild. FirstChild as IDOMNodeEx). Text); 2: id: \u003d StrToInt ((Członkowie [j]. LastChild. FirstChild jako IDOMNodeEx). Text); 3: tytuł: \u003d (Członkowie [j]. LastChild. FirstChild jako IDOMNodeEx). tekst; koniec; koniec; koniec; […]

    W związku z tym w przypadku otrzymania komunikatu o błędzie można skorzystać z omówionej wcześniej funkcji.

    To wszystko na dzisiaj. Następnym razem będziemy kontynuować pracę z API i postarać się uzyskać wszystkie komentarze z bloga.

XML jest coraz częściej używany do przechowywania informacji i wymiany ich między aplikacjami i witrynami sieci Web. Wiele aplikacji używa tego języka jako języka bazowego do przechowywania danych, podczas gdy inne używają go do eksportowania i importowania danych XML. Czas więc, aby programiści zastanowili się, jak dane XML można wykorzystać we własnych aplikacjach.

W tym artykule przyjrzymy się XML Document Object Model (DOM) i implementacji XML DOM firmy Microsoft.

XML DOM to model obiektowy, który zapewnia programiście obiekty do ładowania i przetwarzania plików XML. Model obiektowy składa się z następujących podstawowych obiektów: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap i XMLDOMParseError. Każdy z tych obiektów (z wyjątkiem XMLDOMParseError) zawiera właściwości i metody, które pozwalają uzyskać informacje o obiekcie, manipulować wartościami i strukturą obiektu oraz nawigować po strukturze dokumentu XML.

Spójrzmy na główne obiekty XML DOM i pokażmy kilka przykładów ich użycia w Borland Delphi.

Korzystanie z XML DOM w Borland Delphi

Aby korzystać z Microsoft XML DOM w aplikacjach Delphi, należy podłączyć do projektu odpowiednią bibliotekę typów. W tym celu wykonujemy polecenie Projekt | Biblioteka typów importu i w oknie dialogowym Biblioteka typów importu wybierz bibliotekę Microsoft XML w wersji 2.0 (wersja 2.0), która zwykle znajduje się w pliku Windows \\ System \\ MSXML.DLL

Po kliknięciu przycisku Utwórz jednostkę zostanie utworzony moduł interfejsu MSXML_TLB, który pozwoli nam korzystać z obiektów XML DOM: DOMDocument, XMLDocument, XMLHTTPRequest i wielu innych zaimplementowanych w bibliotece MSXML.DLL. Odniesienie do modułu MSXML_TLB musi znajdować się na liście Zastosowania.

Urządzenie XML DOM

Model obiektu dokumentu przedstawia dokument XML jako strukturę drzewa gałęzi. Interfejsy API XML DOM umożliwiają aplikacjom poruszanie się po drzewie dokumentu i manipulowanie jego gałęziami. Każda gałąź może mieć określony typ (DOMNodeType), zgodnie z którym określa się gałąź nadrzędną i podrzędną. Większość dokumentów XML zawiera gałęzie typu element, atrybut i tekst. Atrybuty to specjalny rodzaj gałęzi i nie są to gałęzie podrzędne. Atrybuty są przetwarzane za pomocą specjalnych metod dostarczanych przez obiekty XML DOM.

Oprócz implementacji interfejsów zalecanych przez World Wide Web Consortium (W3C), Microsoft XML DOM zawiera metody obsługujące XSL, wzorce XSL, przestrzenie nazw i typy danych. Na przykład metoda SelectNodes umożliwia użycie składni wzorca XSL do znajdowania gałęzi w określonym kontekście, a metoda TransformNode obsługuje używanie XSL do wykonywania przekształceń.

Testowy dokument XML

Jako przykładowy dokument XML weźmy katalog z muzyką na dysku CD-ROM, który ma następującą strukturę:

Burleska imperium Bob Dylan USA Columbia 10.90 1985 Ukryj swoje serce Bonnie tylor UK CBS Records 9.90 1988 ... Uwolnij moje serce Joe cocker USA EMI 8.20 1987

Jesteśmy teraz gotowi, aby zacząć przyglądać się modelowi obiektowemu XML DOM, zaczynając od obiektu XMLDOMDocument.

Dokument XML - obiekt XMLDOMDocument

Praca z dokumentem XML zaczyna się od załadowania go. W tym celu używamy metody Load, która ma tylko jeden parametr określający adres URL załadowanego dokumentu. Podczas ładowania plików z dysku lokalnego podawana jest tylko pełna nazwa pliku (w tym przypadku można pominąć protokół file: ///). Jeśli dokument XML jest przechowywany jako ciąg, użyj metody LoadXML, aby załadować ten dokument.

Właściwość Async służy do kontrolowania sposobu ładowania dokumentu (synchronicznego lub asynchronicznego). Domyślnie ta właściwość ma wartość True, co oznacza, że \u200b\u200bdokument jest ładowany asynchronicznie, a sterowanie jest zwracane do aplikacji przed pełnym załadowaniem dokumentu. W przeciwnym razie dokument ładuje się synchronicznie, a następnie musisz sprawdzić wartość właściwości ReadyState, aby zobaczyć, czy dokument został załadowany, czy nie. Można również utworzyć procedurę obsługi dla zdarzenia OnReadyStateChange, która przejmie kontrolę po zmianie wartości właściwości ReadyState.

Poniżej pokazano, jak załadować dokument XML za pomocą metody Load:

Używa ... MSXML_TLB ... procedure TForm1.Button1Click (Sender: TObject); var XMLDoc: IXMLDOMDocument; begin XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // // Tutaj kod // manipuluje dokumentem XML i jego gałęziami // XMLDoc: \u003d Nil; koniec;

Po załadowaniu dokumentu mamy dostęp do jego właściwości. Zatem właściwość NodeName będzie zawierała wartość #document, właściwość NodeTypeString będzie zawierała wartość dokumentu, a właściwość URL będzie zawierała wartość file: /// C: /DATA/DATA.xml.

Obsługa błędów

Szczególnie interesujące są właściwości związane z przetwarzaniem dokumentu podczas jego ładowania. Na przykład właściwość ParseError zwraca obiekt XMLDOMParseError zawierający informacje o błędzie, który wystąpił podczas przetwarzania dokumentu.

Aby napisać procedurę obsługi błędów, możesz dodać następujący kod:

Var XMLError: IXMLDOMParseError; ... XMLDoc.Load („C: \\ DATA \\ DATA.xml”); XMLError: \u003d XMLDoc.ParseError; Jeśli XMLError.ErrorCode<> 0 Wtedy // // Tutaj zajmiemy się błędem // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: \u003d Nil;

Aby zobaczyć, jakie informacje są zwracane w przypadku błędu, zmień następujący wpis katalogu:

Burleska imperium Bob Dylan USA Columbia 10.90 1985

usunięcie elementu zamykającego w drugiej linii:</p><p> <CD> <TITLE>Burleska imperium <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> </p><p>Teraz napiszmy kod, który zwraca wartości właściwości obiektu XMLDOMParseError:</p><p>XMLError: \u003d XMLDoc.ParseError; Jeśli XMLError.ErrorCode<> 0 Następnie z XMLError, Memo1.Lines zaczyna się Dodaj („Plik:” + URL); Add („Code:” + IntToStr (ErrorCode)); Dodaj („Błąd:” + przyczyna); Dodaj („Text:” + SrcText); Dodaj („Line:” + IntToStr (Line)); Dodaj („Stanowisko:” + IntToStr (LinePos)); koniec Else Memo1.Lines.Add (XMLDoc.XML); Koniec;</p><p>i uruchom naszą aplikację. W rezultacie otrzymujemy następujące informacje o błędzie.</p> <p>Jak widać z powyższego przykładu, informacje zwracane przez obiekt XMLDOMParseError są wystarczające do zlokalizowania błędu i zrozumienia przyczyny jego wystąpienia.</p> <p>Teraz przywrócimy element zamykający <TITLE> w naszym dokumencie i kontynuuj dyskusję na temat XML DOM.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Dostęp do drzewa dokumentów</h2> <p>Aby uzyskać dostęp do drzewa dokumentu, możesz pobrać element główny, a następnie powtórzyć jego gałęzie podrzędne lub znaleźć określoną gałąź. W pierwszym przypadku element główny uzyskujemy poprzez właściwość DocumentElement, która zwraca obiekt typu XMLDOMNode. Oto jak użyć właściwości DocumentElement, aby pobrać zawartość każdego elementu podrzędnego:</p><p>Węzeł Var: IXMLDOMNode; Root: IXMLDOMElement; I: Integer; ... Root: \u003d XMLDoc.DocumentElement; Dla I: \u003d 0 do Root.ChildNodes.Length-1 do Begin Node: \u003d Root.ChildNodes.Item [I]; Memo1.Lines.Add (Node.Text); Koniec;</p><p>W przypadku naszego dokumentu XML otrzymujemy następujący tekst.</p> <p>Jeśli interesuje nas konkretna gałąź lub gałąź poniżej pierwszej gałęzi podrzędnej, możemy użyć metody NodeFromID lub metody GetElementByTagName obiektu XMLDOMDocument.</p> <p>Metoda NodeFromID wymaga unikatowego identyfikatora zdefiniowanego w schemacie XML lub definicji typu dokumentu (DTD) i zwraca gałąź z tym identyfikatorem.</p> <p>Metoda GetElementByTagName wymaga ciągu znaków z określonym elementem (tagiem) i zwraca wszystkie gałęzie z tym elementem. Oto jak użyć tej metody, aby znaleźć wszystkich artystów w naszym katalogu na CD-ROM:</p><p>Węzły: IXMLDOMNodeList; Węzeł: IXMLDOMNode; ... Węzły: \u003d XMLDoc.GetElementsByTagName („ARTIST”); Dla I: \u003d 0 do Nodes.Length-1 do Begin Node: \u003d Nodes.Item [I]; Memo1.Lines.Add (Node.Text); Koniec;</p><p>Dla naszego dokumentu XML otrzymamy następujący tekst</p> <p>Należy zauważyć, że metoda SelectNodes obiektu XMLDOMNode zapewnia bardziej elastyczny sposób uzyskiwania dostępu do gałęzi dokumentu. Ale więcej na ten temat poniżej.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Gałąź dokumentu - obiekt XMLDOMNode</h2> <p>Obiekt XMLDOMNode reprezentuje gałąź dokumentu. Napotkaliśmy już ten obiekt podczas pobierania elementu głównego dokumentu:</p><p>Root: \u003d XMLDoc.DocumentElement;</p><p>Aby uzyskać informacje o gałęzi dokumentu XML, możesz skorzystać z właściwości obiektu XMLDOMNode (Tabela 1).</p> <p>Aby uzyskać dostęp do danych przechowywanych w gałęzi, często używa się właściwości NodeValue (dostępnej dla atrybutów, gałęzi tekstowych, komentarzy, instrukcji przetwarzania i sekcji CDATA) lub właściwości Text, która zwraca zawartość tekstową gałęzi, lub właściwości NodeTypedValue. Ta ostatnia może być jednak używana tylko dla oddziałów z wpisanymi elementami.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3> Poruszanie się po drzewie dokumentów</h3> <p>Obiekt XMLDOMNode zapewnia wiele sposobów poruszania się po drzewie dokumentu. Na przykład, aby uzyskać dostęp do gałęzi nadrzędnej, użyj właściwości ParentNode (typ XMLDOMNode), uzyskaj dostęp do gałęzi podrzędnych za pośrednictwem właściwości ChildNodes (typ XMLDOMNodeList), FirstChild i LastChild (typ XMLDOMNode) itp. Właściwość OwnerDocument zwraca obiekt XMLDOMDocument, który identyfikuje sam dokument XML. Właściwości wymienione powyżej ułatwiają nawigację po drzewie dokumentu.</p> <p>Przejdźmy teraz do wszystkich gałęzi dokumentu XML:</p><p>Root: \u003d XMLDoc.DocumentElement; Dla I: \u003d 0 do Root.ChildNodes.Length-1 do Begin Node: \u003d Root.ChildNodes.Item [I]; Jeśli Node.HasChildNodes Then GetChilds (Node, 0); Koniec;</p><p>Jak wspomniano powyżej, SelectNodes obiektu XMLDOMNode zapewnia bardziej elastyczny sposób dostępu do gałęzi dokumentu. Ponadto istnieje metoda SelectSingleNode, która zwraca tylko pierwszą gałąź dokumentu. Obie te metody umożliwiają definiowanie szablonów XSL do wyszukiwania oddziałów.</p> <p>Przyjrzyjmy się procesowi użycia metody SelectNodes do pobrania wszystkich gałęzi, które mają gałąź CD i podgałęzi PRICE:</p><p>Root: \u003d XMLDoc.DocumentElement; Węzły: \u003d Root.SelectNodes („CD / PRICE”);</p><p>Wszystkie podgałęzi PRICE gałęzi CD zostaną umieszczone w kolekcji Nodes. Wrócimy nieco później do omówienia szablonów XSL.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3> Manipulowanie gałęziami potomnymi</h3> <p>Do manipulowania gałęziami potomnymi możemy wykorzystać metody obiektu XMLDOMNode (Tabela 2).</p> <p>Aby całkowicie usunąć zapis dotyczący pierwszego dysku, należy uruchomić następujący kod:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // Pobierz element główny Root: \u003d XMLDoc.DocumentElement; Węzeł: \u003d Root; // Usuń pierwszą gałąź podrzędną Node.RemoveChild (Node.FirstChild);</p><p>Zauważ, że w tym przykładzie usuwamy pierwszą gałąź podrzędną. Sposób usunięcia pierwszego elementu z pierwszej gałęzi podrzędnej pokazano poniżej:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // Pobierz element główny Root: \u003d XMLDoc.DocumentElement; // i pierwsza gałąź podrzędna Node: \u003d Root.FirstChild; // Usuń pierwszą gałąź podrzędną Node.RemoveChild (Node.FirstChild);</p><p>W powyższym przykładzie usunęliśmy nie pierwszą gałąź <CD>…</CD>a pierwszym elementem tej gałęzi jest <TITLE>….

Teraz dodajmy nową gałąź. Poniżej znajduje się kod pokazujący, jak dodać nowy wpis na płycie CD z muzyką:

Var NewNode: IXMLDOMNode; Dziecko: IXMLDOMNode; ... // Utwórz nowy oddział - NewNode: \u003d XMLDoc.CreateNode (1, „CD”, „”); // Dodaj element Dziecko: \u003d XMLDoc.CreateNode (1, „TITLE”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘Pink Floyd’; // Dodaj element <ARTIST> Dziecko: \u003d XMLDoc.CreateNode (1, „ARTIST”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘Division Bell’; // Dodaj element <COUNTRY> Dziecko: \u003d XMLDoc.CreateNode (1, „KRAJ”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d „UK”; // Dodaj element <COMPANY> Dziecko: \u003d XMLDoc.CreateNode (1, „FIRMA”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘EMI Records Ltd.’; // Dodaj element <PRICE>Dziecko: \u003d XMLDoc.CreateNode (1, „PRICE”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d '11 .99 "; // Dodaj element <YEAR> Dziecko: \u003d XMLDoc.CreateNode (1, „YEAR”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d „1994”; // I dodaj gałąź Root.AppendChild (NewNode); ...</p><p>Powyższy kod przedstawia następujące kroki, aby dodać nową gałąź:</p> <ul><li>Tworzenie nowej gałęzi za pomocą metody CreateNode: <ul><li>tworzenie elementu za pomocą metody CreateNode;</li> <li>dodanie elementu do gałęzi przy pomocy metody AppendChild;</li> <li>ustawienie wartości elementu poprzez właściwość Text;</li> <li>… Powtórz te czynności dla wszystkich elementów.</li> </ul></li> <li>Dodanie nowej gałęzi do dokumentu przy użyciu metody AppendChild.</li> </ul><p>Przypomnij sobie, że metoda AppendChild dodaje gałąź na końcu drzewa. Aby dodać gałąź w określone miejsce w drzewie należy skorzystać z metody InsertBefore.</p> <h2> Zestaw gałęzi - obiekt XMLDOMNodeList</h2> <p>Obiekt XMLNodeList zawiera listę gałęzi, które można zbudować za pomocą metod SelectNodes lub GetElementsByTagName, a także uzyskać z właściwości ChildNodes.</p> <p>Omówiliśmy już użycie tego obiektu w przykładzie przedstawionym w sekcji „Poruszanie się po drzewie dokumentu”. W tym miejscu przedstawimy kilka uwag teoretycznych.</p> <p>Liczbę gałęzi na liście można uzyskać jako wartość właściwości Długość. Gałęzie są indeksowane od 0 do Length-1, a każda pojedyncza gałąź jest dostępna poprzez odpowiedni indeksowany element w tablicy Item.</p> <p>Poruszanie się po liście oddziałów można również wykonać przy użyciu metody NextNode, która zwraca następną gałąź na liście lub Nil, jeśli bieżąca gałąź jest ostatnią. Aby powrócić na początek listy, wywołaj metodę Reset.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Twórz i zapisuj dokumenty</h2> <p>Widzieliśmy więc, jak można dodawać gałęzie i elementy do istniejących dokumentów XML. Teraz utwórzmy dokument XML w locie. Przede wszystkim pamiętaj, że dokument można załadować nie tylko z adresu URL, ale także ze zwykłego ciągu. Poniżej pokazano, jak utworzyć element główny, którego można następnie użyć do dynamicznego zbudowania pozostałych elementów (co zostało już omówione w sekcji „Manipulowanie gałęziami potomnymi”):</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; S: WideString; ... S: \u003d „ <CATALOG></CATALOG>'; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.LoadXML (S); Root: \u003d XMLDoc.DocumentElement; Węzeł: \u003d XMLDoc.CreateNode (1, „CD”, „”); Root.AppendChild (węzeł); Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: \u003d Nil;</p><p>Po zbudowaniu dokumentu XML zapisz go do pliku przy użyciu metody Save. Na przykład:</p> <p>XMLDoc.Save ('C: \\ DATA \\ NEWCD.XML');</p> <p>Oprócz zapisywania do pliku metoda Save umożliwia zapisanie dokumentu XML w nowym obiekcie XMLDOMDocument. W takim przypadku dokument jest w pełni przetwarzany, w wyniku czego sprawdzana jest jego struktura i składnia. Oto jak zapisać dokument w innym obiekcie:</p><p>Procedura TForm1.Button2Click (Sender: TObject); var XMLDoc2: IXMLDOMDocument; rozpocznij XMLDoc2: \u003d CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: \u003d Nil; koniec;</p><p>Na koniec należy zauważyć, że metoda Save umożliwia również zapisanie dokumentu XML w innych obiektach COM, które obsługują interfejsy IStream, IPersistStream lub IPersistStreamInit.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Korzystanie z szablonów XSL</h2> <p>Omawiając metodę SelectNodes obiektu XMLDOMNode, wspomnieliśmy, że zapewnia ona bardziej elastyczny sposób dostępu do gałęzi dokumentu. Elastyczność polega na tym, że można określić szablon XSL jako kryterium wyboru oddziałów. Takie szablony zapewniają potężny mechanizm wyszukiwania informacji w dokumentach XML. Na przykład, aby uzyskać listę wszystkich tytułów muzycznych CD-ROM w naszym katalogu, możesz uruchomić następujące zapytanie:</p><p>Aby dowiedzieć się, które płyty artystów zostały wydane w USA, prośba jest sformułowana w następujący sposób:</p><p>Węzły: \u003d Root.SelectNodes („CD / ARTIST”);</p><p>Oto jak znaleźć pierwszy dysk w katalogu:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>i ostatni:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>Aby znaleźć dyski Boba Dylana, możesz uruchomić następujące zapytanie:</p><p>Węzły: \u003d Root.SelectNodes („CD [$ any $ ARTIST \u003d” Bob Dylan ”] / TITLE”);</p><p>i aby uzyskać listę dysków wykonanych po 1985 roku, uruchamiamy następujące zapytanie:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>Bardziej szczegółowe omówienie składni XSL wymaga osobnej publikacji. Aby zaintrygować czytelników i zachęcić do dalszych badań, podam tylko jeden mały przykład możliwego wykorzystania XSL. Powiedzmy, że musimy przekonwertować nasz katalog na zwykłą tabelę HTML. Używając tradycyjnych metod, musimy iterować po wszystkich gałęziach drzewa i dla każdego otrzymanego elementu tworzyć odpowiednie tagi <TD>…</TD>.</p> <p>Używając XSL, po prostu tworzymy szablon (lub arkusz stylów), który określa, co i jak przekształcić. Następnie umieszczamy ten szablon w naszym katalogu - i to wszystko: mamy tekst szablonu XSL, który przekształca katalog w tabelę (Listing 2).</p> <p>Kod nakładający szablon XSL na nasz katalog wygląda następująco:</p><p>Procedura TForm1.Button2Click (Sender: TObject); var XSLDoc: IXMLDOMDocument; begin XSLDoc: \u003d CoDOMDocument.Create; XSLDoc.Load („C: \\ DATA \\ DATA.xsl”); Memo2.Text: \u003d XMLDoc.TransformNode (XSLDoc); XSLDoc: \u003d Nil; koniec;</p><p>Kończąc naszą dyskusję o XSL, należy stwierdzić, że obecnie język ten jest aktywnie używany do transformacji między różnymi dokumentami XML, a także do formatowania dokumentów.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Wniosek</h2> <p>Z oczywistych powodów niemożliwe jest omówienie wszystkich obiektów Microsoft XML DOM i podanie przykładów ich użycia w jednym artykule. Tutaj właśnie poruszyliśmy podstawowe kwestie związane z wykorzystaniem XML DOM w aplikacjach. Stół 3 pokazuje wszystkie obiekty zaimplementowane w Microsoft XML DOM.</p> <p>ComputerPress 12 "2000</p> <p>Pomimo faktu, że temat pracy z XML w Delphi był szeroko dyskutowany w Internecie, pytania na ten temat są często zadawane na wszelkiego rodzaju forach. <br></p><p>Też to napisałem, ale chciałbym wrócić do rzeczywistego przypadku szybkiego parsowania pliku XML i wyodrębniania danych, co robiłem dzisiaj w pracy. Uzyskanie niezbędnych danych zajęło mi nie więcej niż 5 minut. <br></p><p>Tło. Dziś konieczne było przetwarzanie danych o zainstalowanych programach na komputerach użytkowników (tak, tak, identyfikujemy piratów :)). Dział techniczny dostarczył mi te informacje, odebrane niczego niepodejrzewającym użytkownikom przez sieć używającą WMI. Program, którego używali, tworzy raporty w formacie XML. W związku z tym przywieźli mi górę plików XML o dość złożonej strukturze, z których musiałem tylko wyodrębnić nazwę zainstalowanego oprogramowania. <br><span><br><p>Leczenie. Po ręcznym przejrzeniu kilku plików zdałem sobie sprawę, że starzenie się nie zajmie dużo czasu, i postanowiłem napisać mały konwerter. Po uruchomieniu Delphi wybrałem obiekt XML DataBinding z repozytorium i wprowadziłem do niego jeden z plików. Domyślnie zostawiłem wszystkie ustawienia i parametry, w wyniku czego mam moduł z dużą liczbą klas i interfejsów do dostępu do elementów tego pliku XML. Długo nie zajmowałem się strukturą klas, od razu przeszedłem do napisania konwertera. <br></p><p>W nowej aplikacji konsolowej napisałem dość prosty kod: <br></p> <br>program XML2TXT;</p><p>używa <br> Formularze, <br> Klasy, SysUtils, <br> SoftwareXML w „SoftwareXML.pas”;</p><p>procedura CovertXML2Text; <br>var <br> softbase: IXMLSTDSoftwareType; <br> i: liczba całkowita; <br> sr: TSearchRec; <br> CurDir: string; <br> ExportFile: TStringList; <br>zaczynać <br> CurDir: \u003d IncludeTrailingPathDelimiter (ExtractFilePath (Application.ExeName)); <br> if FindFirst (CurDir + "*. xml", faAnyFile, sr) \u003d 0 to <br> powtarzać <br> ExportFile: \u003d TStringList.Create; <br> softbase: \u003d LoadSTDSoftware (Pchar (CurDir + sr.Name)); <br> for i: \u003d 0 to softbase.InstalledSoftware.source.software.Count - 1 do <br> ExportFile.Add (softbase.InstalledSoftware.source.software [i] .DisplayName); <br> ExportFile.Sort; <br> ExportFile.SaveToFile (CurDir + softbase.InstalledSoftware.Source.servername + ". Txt"); <br> ExportFile.Free; <br> aż do FindNext (sr) 0; <br>koniec;</p><p>zaczynać <br> Application.Initialize; <br> CovertXML2Text; <br>koniec. <br></p><p>W rezultacie otrzymałem jeden edytor tekstu dla każdego komputera w siatce zawierającej listę zainstalowanego oprogramowania. <br></p><p>Czuję, że ten kod będzie wymagał wyjaśnienia. Na przykład, dlaczego użyłem modułu Forms w aplikacji konsoli i wywołałem procedurę Application.Initialize;? <br></p><p>To naprawdę proste - to mały hack, który pozwala na użycie powiązania danych XML w aplikacji konsoli. Ponieważ uparcie odmawiał zainicjowania klasy do pracy z XML. Nie rozgryzłem jeszcze prawdziwych powodów - dzisiaj był ważny czas, spędziłem już 4 z 5 minut walcząc z tym błędem. :) Myślę, że zajmę się tym problemem później i napiszę, jaki jest prawdziwy powód. <br></p><p>Dziwna klasa softbase została utworzona z pliku XML - to nazwa elementu głównego, a softbase.InstalledSoftware.source.software [i] .DisplayName po prostu nawiguje zagnieżdżone elementy do żądanego i uzyskuje jego wartość. <br></p><p>Tak wygląda jeden z najszybszych sposobów pracy z XML w Delphi. <br></p> <p>Ostatnio wiele uwagi poświęcono budowaniu systemów e-biznesu, czy też jak się je nazywa - B2B (business to business). Uwzględniając zalecenia dotyczące budowy systemów wymiany strumieniowej organu koordynującego technologie internetowe - Konsorcjum WWW: nacisk kładziony jest na technologie XML i budowę systemów wymiany dokumentów XML.</p> <p>Zaletą wykorzystania XML w e-biznesie jest wysoka wydajność systemów B2B przy niskich kosztach ich tworzenia dzięki czytelnej i wizualnej prezentacji ustrukturyzowanych informacji, możliwości wykorzystania nowoczesnych protokołów sieciowych oraz tworzenia systemów biznesowych w czasie rzeczywistym.</p> <p>Niezależność prezentacji informacji w postaci dokumentów XML pozwala różnym firmom zajmującym się e-biznesem na tworzenie oprogramowania niezależnego od siebie.</p> <p>We wszystkich systemach centrala jest z reguły budowana według tego samego schematu, z wykorzystaniem zapytań HTTP. SSL jest używany jako protokół bezpieczeństwa informacji (ale to osobny temat).</p> <p>Jedną z możliwych opcji przetwarzania komunikatów XML jest tworzenie aplikacji BIN / CGI (ISAPI) lub komponentów COM (serwera), które generują lub przetwarzają dokumenty XML.</p> <p>Z jednej strony aplikacja pełni rolę klienta, który wysyła żądanie HTTP w trybie POST, z drugiej strony znajduje się serwer WEB, po stronie którego przetwarzane jest żądanie i wystawiana jest odpowiedź. Dokumenty XML są używane w wymianie informacji.</p> <p>Jedną z najbardziej wydajnych opcji implementacji jest użycie istniejącego parsera XML, który obsługuje model DOM. Taki parser jest pakietem dystrybucyjnym Win'98 lub integralną częścią IE 4.7 i nowszych (dla Win'95) i reprezentuje serwer COM umieszczony w bibliotece msxml.dll.</p> <p>Component Object Model (COM) - prezentuje hermetyzowane dane i metody w jedną całość oraz sposób na dostęp do nich poprzez system interfejsów. Korzystając z narzędzi Delphi, dostęp do klas obiektu COM jest dość łatwy (kilka klas może być zawartych na jednym serwerze COM). Dostęp do obiektów uzyskuje się poprzez zainicjowanie instancji klasy za pośrednictwem systemu interfejsu. Opis interfejsów odbywa się za pomocą języka definicji interfejsów (IDL), który może być wykonywany automatycznie za pośrednictwem środowiska.</p> <p>Narzędzia Delphi służą do importowania z serwera COM <i>msxml.dll</i>budowane są pliki opisu interfejsu IDL i plik binarnego opisu typów bibliotek - TLB. Ta operacja jest wykonywana za pośrednictwem menu systemowego: <b>Projekt | Import biblioteki typów:</b>(obrazek 1). Następnie pojawia się okno dialogowe (Rysunek 2), w którym należy wybrać obiekt COM (w naszym przypadku obiekt jest zarejestrowany pod nazwą „Microsoft.XMLDom (wersja 2.0)”) i utworzyć plik TLB (przycisk <b>Utwórz jednostkę</b>). Korzystając z pliku TLB, framework generuje plik opisu serwera COM Pascal - MSXML_TLB.pas</p> <p>Plik MSXML_TLB.pas zawiera opis wszystkich interfejsów, stałych i klas serwera COM.</p> <p>Aby uzyskać dostęp do obiektów elementu COM, potrzebujesz w dyrektywie <b>ZASTOSOWANIA</b>dodaj nazwę pliku opisu biblioteki (MSXML_TLB.pas). Poniżej znajduje się prosty program korzystający ze standardowego parsera DOM msxml.dll, który ładuje dokument XML i wyświetla go w elemencie pola tekstowego Memo1.</p> <b>używa</b> Windows, wiadomości, SysUtils, klasy, grafika, kontrolki, formularze, okna dialogowe, OleServer, MSXML_TLB, StdCtrls; <b>rodzaj</b> TForm1 \u003d <b>klasa</b>(TForm) Button1: TButton; Memo1: TMemo; <b>procedura</b> Button1Click (Sender: TObject); <b> koniec;</b> <b>var</b> Form1: TForm1; <b>realizacja</b> ($ R * .DFM) <b>Procedura</b>TForm1.Button1Click (Sender: Tobject); <span> // deklaracja klasy obiektu DOMDocument;</span> <b>var</b>coDoc: CoDOMDocument; <span> // klasa zgodna z interfejsem IDOMDocument;</span> <b>var</b>Doc: IXMLDOMDocument; <b>zaczynać</b> <span> // utwórz instancję obiektu DOMDocument;</span> Doc: \u003d coDoc.Create; <span> // wywołanie metody Load instancji obiektu DOMDocument;</span> Doc.load ("data.xml"); <span> // dostęp do właściwości xml instancji DOMDocument;</span> Memo1.Text: \u003d Doc.xml; <b>koniec;</b> <b>koniec.</b> <h2>DOM Concept - Document Object Model</h2> <p>Każdy dokument XML jest reprezentowany jako zbiór wielu obiektów (klas), za pomocą których możliwy jest dostęp do poszczególnych elementów (pól obiektów). DOM - interfejs opisuje dostęp zarówno do prostych obiektów typu DOMString lub CharacterData, jak i do części lub poszczególnych elementów dokumentu XML: DOMFragmentElement, DOMNode, DOMElement.</p> <p>Poniżej przedstawiono najważniejsze właściwości i metody obiektów XMLDOMDocument, XMLDOMNode, XMLDOMNodeList. Należy zauważyć, że przedstawione poniżej metody i funkcje obiektów Document Object Model (DOM) są używane przez parser Microsoft XML msxml.dll i są nieco szersze niż model DOM zatwierdzony przez Konsorcjum W3C.</p> <p>Bardziej szczegółowy opis interfejsu obiektu DOM można znaleźć pod adresem</p> <table cellspacing="0" cellpadding="4" width="500" border="1"><tbody><tr><td valign="top" colspan="2"> Obiekt XMLDOMDocument</td> </tr><tr><td valign="top" colspan="2">Reprezentuje najwyższy poziom hierarchii obiektów i zawiera metody pracy z dokumentem: ładowanie go, analizowanie, tworzenie elementów, atrybutów, komentarzy itp. ...</td> </tr><tr><td valign="top" colspan="2"><b>Nieruchomości</b> </td> </tr><tr><td valign="top" width="39%"><b>Async</b> </td> <td valign="top" width="61%">Właściwość identyfikująca aktualny tryb przetwarzania</td> </tr><tr><td valign="top" width="39%" height="19"><b>Błąd przetwarzania</b> </td> <td valign="top" width="61%" height="19">Zwraca odwołanie do obiektu obsługi błędów XMLDOMParseError</td> </tr><tr><td valign="top" width="39%"><b>Włącz - wyłącz weryfikację dokumentów.</b> </td> <td> </td> </tr><tr><td valign="top" width="39%"><b>url</b> </td> <td valign="top" width="61%">Zwraca adres URL dokumentu</td> </tr><tr><td valign="top" width="39%"><b>documentElement</b> </td> <td valign="top" width="61%">Zawiera odniesienie do elementu głównego dokumentu jako obiekt XMLDOMElement.</td> </tr><tr><td valign="top" colspan="2"><b>Metody</b> </td> </tr><tr><td valign="top" width="39%"><b>załaduj (url) <br>loadXML (xmlString)</b> </td> <td valign="top" width="61%">Wczytuje dokument XML,</td> </tr><tr><td valign="top" width="39%"><b>zapisz (objTarget)</b> </td> <td valign="top" width="61%">Zapisuje dokument XML do pliku</td> </tr><tr><td valign="top" width="39%"><b>anulować</b> </td> <td valign="top" width="61%">Przerwanie procesu ładowania i przetwarzania dokumentu.</td> </tr><tr><td valign="top" width="39%"><b>createAttribute (nazwa)</b> </td> <td valign="top" width="61%">Tworzy nowy atrybut o określonej nazwie dla bieżącego elementu.</td> </tr><tr><td valign="top" width="39%"><b>createNode (typ, nazwa, nazwaSpaceURI)</b> </td> <td valign="top" width="61%">Tworzy węzeł określonego typu i nazwy</td> </tr><tr><td valign="top" width="39%"><b>createElement (tagName)</b> </td> <td valign="top" width="61%">Tworzy element dokumentu o określonej nazwie.</td> </tr><tr><td valign="top" width="39%"><b>createTextNode (dane)</b> </td> <td valign="top" width="61%">Tworzy tekst w dokumencie</td> </tr><tr><td valign="top" width="39%"><b>getElementsByTagName (zmienna)</b> </td> <td valign="top" width="61%">Zwraca odniesienie do kolekcji elementów dokumentu o podanej nazwie</td> </tr><tr><td valign="top" width="39%"><b>nodeFromID (idString)</b> </td> <td valign="top" width="61%">Znajdowanie przedmiotu według identyfikatora</td> </tr></tbody></table><br><table cellspacing="0" cellpadding="4" width="500" border="1"><tbody><tr><td valign="top" colspan="2"> <b>Obiekt XMLDOMNode</b> </td> </tr><tr><td valign="top" colspan="2">Obiekt XMLDOMNode, który implementuje podstawowy interfejs DOM <b>Węzeł</b>, służy do manipulowania oddzielnym węzłem drzewa dokumentu. Jego właściwości i metody pozwalają uzyskać i zmienić pełne informacje o aktualnym węźle - jego typ, nazwa, pełna nazwa, jego zawartość, lista elementów potomnych itp.</td> </tr><tr><td valign="top" colspan="2"><b>Nieruchomości</b> </td> </tr><tr><td valign="top" width=" "><b>nodeName, baseName</b> </td> <td valign="top" width="65%">Zwraca nazwę bieżącego węzła.</td> </tr><tr><td valign="top" width="35%"><b>prefiks</b> </td> <td valign="top" width="65%">Zwraca prefiks Namespace.</td> </tr><tr><td valign="top" width="35%"><b>typ danych</b> </td> <td valign="top" width="65%">Określa typ zawartości bieżącego węzła</td> </tr><tr><td valign="top" width="35%"><b>nodeType, nodeTypeString</b> </td> <td valign="top" width="65%">Zwraca typ bieżącego węzła:</td> </tr><tr><td valign="top" width="35%"><b>atrybuty</b> </td> <td valign="top" width="65%">Pobiera listę atrybutów bieżącego węzła jako kolekcję XMLDOMNamedNodeMap.</td> </tr><tr><td valign="top" width="35%"><b>tekst</b> </td> <td valign="top" width="65%">Zwraca zawartość bieżącego poddrzewa jako tekst</td> </tr><tr><td valign="top" width="35%"><b>xml</b> </td> <td valign="top" width="65%">Zwraca reprezentację XML bieżącego poddrzewa.</td> </tr><tr><td valign="top" width="35%"><b>nodeValue</b> </td> <td valign="top" width="65%">Zwraca zawartość bieżącego węzła.</td> </tr><tr><td valign="top" width="35%"><b>childNodes</b> </td> <td valign="top" width="65%">Zwraca listę elementów podrzędnych jako XMLDOMNodeList.</td> </tr><tr><td valign="top" width="35%"><b>firstChild, lastChild</b> </td> <td valign="top" width="65%">Zwraca pierwsze / ostatnie dziecko</td> </tr><tr><td valign="top" width="35%"><b>previousSibling, nextSibling</b> </td> <td valign="top" width="65%">Zwraca poprzedni / następny element równorzędny.</td> </tr><tr><td valign="top" width="35%"><b>parentNode</b> </td> <td valign="top" width="65%">Zawiera łącze do elementu nadrzędnego.</td> </tr><tr><td valign="top" width="35%"><b>ownerDocument</b> </td> <td valign="top" width="65%">Zwraca wskaźnik do dokumentu zawierającego bieżący węzeł.</td> </tr><tr><td valign="top" colspan="2"><b>Metody</b> </td> </tr><tr><td valign="top" width="35%"><b>appendChild (newChild)</b> </td> <td valign="top" width="65%">Dodaje nowe dziecko do bieżącego węzła.</td> </tr><tr><td valign="top" width="35%"><b>insertBefore (newChild, refChild)</b> </td> <td valign="top" width="65%">Wstawia węzeł podrzędny, umieszczając go w bieżącym poddrzewie „po lewej” węzła określonego przez parametr refChild.</td> </tr><tr><td valign="top" width="35%"><b>cloneNode (głęboki)</b> </td> <td valign="top" width="65%">Tworzy kopię bieżącego elementu.</td> </tr><tr><td valign="top" width="35%"><b>getAttribute</b><b>(imię) <br> </b><b>getAttributeNode</b><b><span> (imię) <br>setAttribute (nazwa, wartość) <br>setAttributeNode (XMLDOMAttribute)</span> </b> </td> <td valign="top" width="65%">Dostęp do atrybutów (tworzenie, odczyt, zapis) obiektu. Nazwa to nazwa atrybutu, wartość to jego wartość. Zwraca obiekt XMLDOMAttribute.</td> </tr><tr><td valign="top" width="35%"><b>replaceChild (noweDziecko, stareDziecko) removeChild (stareDziecko)</b> </td> <td valign="top" width="65%">Zastąpienie obiektu oldChild aktualnej listy obiektów podrzędnych na newChild. Usuwanie obiektu oldChild</td> </tr><tr><td valign="top" width="35%"><b>selectNodes (patternString) selectSingleNode (patternString)</b> </td> <td valign="top" width="65%">Zwraca obiekt XMLDOMNodeList wybrany przez wzorzec wyszukiwania lub pierwszy węzeł</td> </tr><tr><td valign="top" width="35%"><b>transformNode (arkusz stylów) <br>transformNodeToObject (arkusz stylów, outputObject)</b> </td> <td valign="top" width="65%">Przypisuje arkusz stylów do poddrzewa bieżącego węzła i zwraca ciąg będący wynikiem przetwarzania. Parametr jest odwołaniem do obiektu DOMDocument, który zawiera instrukcje XSL.</td> </tr></tbody></table><br><h2>Wykorzystanie XML w biznesie.</h2> <p>Aby uzyskać jaśniejszy obraz, potrzebne jest wyjaśnienie i dlaczego wszystko to jest potrzebne, aby zrozumieć, jak to działa:</p> <p>Budując system B2B lub korporacyjny ERP, organizując wymianę informacji dokumentów XML pomiędzy przedsiębiorstwami lub oddziałami pr-I, wykorzystywany jest sprawnie sprawdzony system przesyłania informacji oparty o istniejące serwery WEBowe po protokołach HTTP.</p> <p>Z jednej strony aplikacja pełni rolę klienta, który wysyła żądanie HTTP w trybie POST, z drugiej strony jest serwer WEB, po stronie którego przetwarzane jest żądanie i wystawiana jest odpowiedź. Dokumenty XML służą do wymiany.</p> <p>Na przykład w prostym korporacyjnym systemie ERP, programie księgowym (ACS Accounting), konieczne jest sporządzenie wniosku o wystawienie faktury i przesłanie jej do oddziału posiadającego magazyn (ACS Warehouse). AWP Podobne stwierdzenie problemu podczas tworzenia systemu B2B, gdy Przedsiębiorstwo A żąda dostępności produktów (składa zamówienie na zakup) od Dostawcy B.</p> <p>Przedsiębiorstwo A i jego program działają jako klient. Magazyn obsługiwany jest przez Dostawcę B, który posiada kompleks magazynowy z bazą danych na serwerze SQL. Wymiana odbywa się za pośrednictwem firmowego serwera WEB Dostawcy V.</p> <p>Poniżej znajduje się następujący typowy algorytm wymiany:</p> <br>Rycina 3. <ol><li><b>Przedsiębiorstwo A</b>inicjuje <b>proces A</b>(zamówienie produktu), który działa jako klient WEB.</li><li><b>Proces A</b>generuje dokument XML (na przykład żądanie faktury) i przesyła go jako żądanie HTTP POST do serwera WEB dostawcy B. Identyfikator zasobu aplikacji przetwarzającej jest używany jako URI. Identyfikator URI może być taki sam dla wszystkich typów dokumentów lub indywidualny dla każdego typu. Wszystko zależy od struktury serwera B2B (WEB).</li><li>Serwer WEB analizuje żądanie i generuje serwer <b>Proces B</b>przekazując treść dokumentu XML jako parametr. <br>Proces B jest uruchamiany przez serwer sieciowy i jest przetwarzany jako strona ASP, CGI (ISAPI) - aplikacja lub serwer JAVA (aplikacja serwerowa)</li><li><b>Proces B</b>- generuje żądanie do serwera bazy danych SQL.</li><li>Serwer SQL wykonuje niezbędne operacje w bazie danych, generuje odpowiedź i zwraca ją <b>Proces B</b>.</li><li>Zgodnie z odpowiedzią z serwera SQL <b>Proces B</b> generuje dokument XML (odpowiedź) i zwraca go jako odpowiedź na żądanie http do aplikacji klienckiej.</li><li>Ponadto, w zależności od sytuacji po stronie klienta, tworzone jest nowe żądanie http lub sesja kończy się.</li> </ol><h2>Kilka słów o organizacji przepływu dokumentów.</h2> <p>Ogólna zasada tworzenia systemu wymiany dokumentów XML jest następująca:</p><ul><li><b>po pierwsze</b>- opracowanie schematu blokowego dokumentów elektronicznych i ich struktury;</li><li><b>po drugie</b>- tworzenie tabel funkcji procesu (podprocesów) tj. jaką funkcję w odniesieniu do jakiego dokumentu XML zaimplementuje każdy proces.</li> </ul><p>Każdy dokument XML, podobnie jak dokument HTML, musi składać się z nagłówka wiadomości (informacje zawarte w tagach) i treści wiadomości (w przypadku żądania informacje te są otoczone tagami, aby odpowiedzieć na żądanie). Aby dokument XML był dobrze sformułowany, konieczne jest na przykład obramowanie jego dwóch części składowych „Nagłówek” i „Żądanie” tagami. Poniżej przedstawiono typ typowego dokumentu:</p> <p>Nagłówek (rys. 4), w przeciwieństwie do dokumentu HTML, musi zawierać różnego rodzaju informacje serwisowe, w tym informacje o rodzaju przesyłanego dokumentu i procesie jego przetwarzania. Treść dokumentu zostaje wprowadzona do przetwarzania informacji, tj. zawartość otoczona tagami. Należy zwrócić uwagę, że struktura nagłówków powinna być taka sama dla wszystkich typów dokumentów.</p> <p>Dla Procesu uruchamianego przez serwer zaleca się (ale nie jest to konieczne) zbudowanie algorytmu przetwarzania w następujący sposób:</p> <img src='https://i2.wp.com/codenet.ru/np-includes/upload/2005/01/05/128666.jpg' height="500" width="408" loading=lazy><br>Rysunek 6. <h2>Kilka podstawowych punktów podczas tworzenia strony klienta</h2> <p>Jak już wyjaśniono, podczas tworzenia dokumentu XML używana jest jego reprezentacja w postaci modelu DOM. Poniżej znajduje się przykład fragmentu tekstowego Delphi programu generującego nagłówek XML wiadomości.</p> <b>procedura</b>TThread1.HeaderCreate (Sender: Tobject); <b>var</b> <span> // deklaracja klasy, potrzebna do utworzenia</span> coDoc: CoDomDocument; <span> // obiekt XMLDomDocument</span> Doc: DomDocument; r: IXMLDOMElement; Węzeł: IXMLDOMElement; // DOMText txt: IXMLDOMText; // DOMAttribute attr: IXMLDOMAttribute; <b>zaczynać</b> <span> // utwórz dokument DOM</span> Doc: \u003d coDoc.Create; Doc.Set_async (false); <span> // początkowa inicjacja dokumentu DOM</span> Doc.LoadXML („ <Header/>"); <span> // utwórz DOMElement (tag<<b>Nadawca</b>>) </span> Węzeł: \u003d Doc.createElement ("Sender"); <span> // utwórz węzeł tekstowy " <b>Typhoon LLC</b>" </span> txt: \u003d Doc.createTextNode ("Typhoon LLC"); <span> // przypisanie do węzła<<b>Nadawca</b>\u003e wartość</span> <span> // węzeł tekstowy " <b>Typhoon LLC</b>" </span> Node.appendChild (txt); <span> // dodaj element<<b>Nadawca</b>\u003e do katalogu głównego dokumentu jako dziecko</span> r.appendChild (węzeł); <span> <<b>Z</b>> </span> Węzeł: \u003d Doc.createElement ("Od"); txt: \u003d Doc.createTextNode ("http://tayfun.ru/xml/default.asp"); Node.appendChild (txt); r.appendChild (węzeł); <span> // podobne operacje dla tagu<<b>Do</b>> </span> Węzeł: \u003d Doc.createElement ("Do"); txt: \u003d Doc.createTextNode ("http://irbis.ru"); Node.appendChild (txt); r.appendChild (węzeł); <span> // utwórz DOMElement ()</span> Węzeł: \u003d Doc.createElement ("TypeDocument"); <span> // utwórz węzeł XMLDOMAttribute</span> Att: \u003d Doc.createAttribute ("Id", "Zamówienie"); <span> // <TypeDocument Id="Order"/> </span> Node.appendChild (Att); r.appendChild (węzeł); <b>koniec;</b> <p>Należy zaznaczyć, że deklaracja zmiennej coDoc: CoDomDocument oraz Doc: DomDocument, a także jej utworzenie metodą Create (Doc: \u003d coDoc.Create;) odbywa się jednorazowo. Deklaracja zmiennej znajduje się w sekcji opisującej zmienne globalne, a nie w procedurze lokalnej, jak zostało to zademonstrowane dla jasności w tym przykładzie (czyli jedna zmienna globalna typu DomDocument na moduł programu).</p> <p>Efektem pracy powyższego programu będzie utworzony nagłówek, zastosowany do naszego przykładowego dokumentu xml: pokazanego na rysunku 5.</p> <img src='https://i2.wp.com/codenet.ru/np-includes/upload/2005/01/05/128662.gif' height="116" width="298" loading=lazy><br>Rycina 5. <p><img src='https://i0.wp.com/codenet.ru/np-includes/upload/2005/01/05/128664.gif' height="179" width="385" loading=lazy><br>Rysunek 6.</p><p>Główną zaletą przesyłania informacji w postaci dokumentów XML jest to, że możliwe jest utworzenie wiadomości przy użyciu niezależnych struktur tabel w DBMS zarówno po stronie odbiorczej, jak i przesyłanej. Posługując się naszym przykładem, załóżmy, że wymagane jest przesłanie informacji o fakturach przedsiębiorstwa A z DBMS o strukturze pokazanej na rysunku 6</p> <p>Aby wygenerować dokument xml zawierający fakturę, najpierw budowane jest zapytanie SQL (zapytanie A) z informacjami o samej fakturze:</p> <b>WYBIERZ</b> * FROM Invoice_General <b>GDZIE</b> InvoiceNum \u003d: num <b>WYBIERZ</b>Towar, ilość, cena, HZ_cod <b>Z</b>Dobra <b>GDZIE</b> InvoiceNum \u003d: num <span> //: num - parametr określający numer faktury.</span> <p>Poniżej znajduje się część programu, która generuje treść dokumentu xml:</p> <b>procedura</b> TThread1.DataBodyCreate (Sender: Tobject); <b>var</b> <span> // deklaracja klasy i obiektu XMLDomDocument</span> // coDoc: CoDomDocument; <span> // musi być globalne dla całego modułu.</span> // Doc: DomDocument; <span> // zadeklaruj obiekty DOMElement</span> r: IXMLDOMElement; // DOMElement; Węzeł, Node2: IXMLDOMElement; Node3, Node4: IXMLDOMElement; // DOMText txt: IXMLDOMText; str: String; <span> // Numer faktury: <b>liczba całkowita;</b> - zmienna globalna - // ma wartość 987654 // zapytanieA, zapytanieB: <b>Strunowy;</b> - zmienna globalna, // ma wartość odpowiadającą zapytaniu // zapytanieA - zapytanie A z ogólnymi informacjami o fakturze // zapytanieB - zapytanie B informacje o towarze opisanym w // fakturze (patrz tekst)</span> <b>zaczynać</b> Query.Close; <span> // zobacz tekst „żądanie A”</span> Query.Text: \u003d queryA; <span> // wykonaj żądanie</span> Query.ExecSQL; Query.Open; <span> // pobierz adres elementu głównego</span> r: \u003d Doc.Get_documentElement; Node2: \u003d Doc.createElement ("Żądanie"); <span> // utwórz DOMElement (tag)</span> Węzeł: \u003d Doc.createElement ("Faktura"); <span> // dodaj element do katalogu głównego</span> r.appendChild (Node2); <span> // dodaj element do</span> Node2. appendChild (Node); <span> // utwórz DOMElement (tag)</span> Node3: \u003d Doc.createElement ("Depurture"); <span> // dodaj element do</span> Węzeł. appendChild (Node3); <span> // dostęp do pola „Depurture” wniosku</span> str: \u003d Query.FieldByName ("Depurture"). AsString; <span> // utwórz węzeł tekstowy \u003d wartość pola</span><span> // przypisz wartość do węzła</span> <span> // węzeł tekstowy, zmienna str</span> Node.appendChild (txt); <span> // podobne operacje dla tagu <Destination>, <DataSend>, // <DataDepurture>, <Currency> // <DestinationCompany> (Pole DB „Odbiorca”)</span> Węzeł: \u003d Doc.createElement ("Miejsce docelowe"); <span> // nazwa pola bazy danych nie może być taka sama jak nazwa</span> str: \u003d Query.FieldByName ("Odbiorca") .AsString; <span> //, to jest zaleta używania</span> txt: \u003d Doc.createTextNode (str); <span> // DOM interfejsu przed DBMS, który obsługuje interfejs XML, // jak ORACLE 8i lub Ms SQL 2000</span> Node.appendChild (txt); ... <span> // generowanie zapytania o specyfikację towaru</span> <span> // zamknij żądanie dostępu</span> Query.Close; <span> // zobacz w tekście "żądanie B", info. O towarach</span> Query.Text: \u003d queryВ; <span> // przypisanie wartości parametrów</span> Query.Params.AsInteger: \u003d InvoiceNumber; <span> // wykonaj żądanie</span> Query2.ExecSQL; <span> // otwarty dostęp do żądania danych</span> Query.Open; <span> // utwórz DOMElement (tag)</span> Node3: \u003d Doc.createElement ("Imems"); <span> // dodaj element do</span> Węzeł. appendChild (Node3); <span> // pętla przez wszystkie wiersze zapytania</span> <b>podczas</b> <b>nie</b> Eof.Query <b>robić</b> begin Node4: \u003d Doc.createElement ("Imem"); <span> // dodaj element do</span> Node3.appendChild (Node4); <span> // generowanie danych dla tagu</span> str: \u003d Query.FieldByName ("Cena"). AsString; txt: \u003d Doc.createTextNode (str); Node.appendChild (txt); ... <span>// podobne operacje dla tagów <HZ_Cod>, <Quality>, <GoodName> </span> <b>koniec;</b> <b>koniec;</b> <p>W wyniku tej procedury generowany jest następujący tekst dokumentu XML:</p> <table width="100%"><tbody><tr><td align="middle"><br><img src='https://i1.wp.com/codenet.ru/np-includes/upload/2005/01/05/128661.gif' width="100%" loading=lazy></td> </tr></tbody></table><p>Aby utworzyć żądanie, użyj metody Open obiektu <b>IXMLHttpRequest</b>:</p> <b>procedura</b> Open (const bstrMethod, - method type \u003d "POST" bstrUrl, - varAsync server url, - asynchronous / synchronous communication mode \u003d true bstrUser, - username for authentication bstrPassword) - password <h2>Tworzenie strony serwerowej przetwarzania dokumentów</h2> <p>Jak wspomniano wcześniej, przetwarzanie żądania HTTP może być obsługiwane przez aplikacje CGI lub serwlety Java. Możliwe jest również pisanie stron ASP. Ale w tym przypadku transfer danych jest możliwy tylko metodą „GET” poprzez ciąg zapytania. Jednak obsługa żądań HTTP dotyczących stron ASP jest bardziej wydajna niż aplikacja CGI. Jednak moim zdaniem nie ma znaczenia, jak go przetworzyć, ale ważniejsze jest, aby zdecydować, jak zbudować program przetwarzający, a nie za pomocą jakich środków.</p> <p>Jeśli z poprzedniego rozdziału zbadaliśmy możliwości tworzenia dokumentu XML, to zadaniem aplikacji serwerowej jest odwrotne - parsowanie dokumentów XML. Poniżej znajduje się część programu, która analizuje dokument xml:</p> <b>procedura</b>Tthread1.DataParser (Sender: Tobject); <b>var</b> <span>// zadeklaruj obiekty DOMElement</span> r, FNode: IXMLDOMElement; Str, Filename: String; parm: String; <span>// deklaracja soclass i</span> CoDocXML, CoDocXSL, CoDocResult: CoDomDocument; <span>// obiekt XMLDomDocument</span> XMLDoc, XSLDoc, ResultDoc: DomDocument; <span>// HttpStr: String; - zmienna globalna zawierająca ciąg żądania HTTP</span> <b>Zaczynać</b> XMLDoc: \u003d coDocXML.Create; XMLDoc.LoadXML (HttpStr); <span> // pobierz adres elementu głównego</span> r: \u003d Doc.Get_documentElement; <span> // pobierz wartość elementu</span> FNode: \u003d r.SelectSingleNode ("// TypeDocument"); <span> // pobierz wartość atrybutu id \u003d "Order"</span> FileName: \u003d FNode.GetAttibute ("id"); <span> // i tworząc nazwę pliku Order.xsl</span> NazwaPliku: \u003d NazwaPliku + ". Xsl"; <span> // utwórz dokument XSLDoc</span> XSLDoc: \u003d coDocXSL.Create; XSLDoc.LoadXML (nazwa pliku); <span> // utwórz dokument XMLDoc</span> ResultDoc: \u003d coDocResult.Create; <span> // ustaw synchroniczny tryb przetwarzania</span> ResultDoc.Set_async (false); <span> // ustaw sprawdzanie analizy</span> ResultDoc.validateOnParse: \u003d true; <span> // parsowanie XMLDoc przy użyciu szablonu XSL</span> XMLDoc.transformNodeToObject (XSLDoc, ResultDoc); <span> // zmiennej Str jest przypisywana wartość tekstowa</span> <span> // powstałego dokumentu.</span> Str: \u003d ResultDoc.text; <span> // znajdź element</span> FNode: \u003d r.SelectSingleNode ("// InvoiceNumber"); <span> // i pobierz wartość elementu</span> parm: \u003d FNode.text; <span> // zamknij żądanie dostępu</span> Query.Close; Query.Text: \u003d Str; <span> // przypisanie wartości parametru</span> Query.Params.AsString: \u003d parm; <span> // wykonaj żądanie</span> Query.ExecSQL; <b>koniec;</b> <p>Cała najważniejsza cecha parsowania polega na użyciu szablonu XSL, który jest tworzony indywidualnie dla każdego typu dokumentu. Wynikiem analizy jest ciąg zapytania SQL. Następnie wykonanie wygenerowanego ciągu zapytania SQL spowoduje niezbędne zmiany danych w DBMS.</p> <p>Zaletą korzystania z parsowania za pomocą szablonu jest również to, że uzyskujesz pewien rodzaj elastyczności danych i uzyskujesz całkowitą niezależność algorytmu od kodu programu. Poniżej znajduje się tekst szablonu XSL używanego do przetwarzania dokumentu ZAMÓWIENIA:</p><p> <!-- файл Order.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <xsl:for-each select="//header"> INSERT into TABREG (FROM, TO, TYPEDOC, body) VALUES (" <xsl:value-of select="from" />", "<xsl:value-of select="to" />", "<xsl:value-of select="TypeDocument/@id" />") </xsl:for-each> <xsl:for-each select="//item"> WSTAW DO TOWARÓW (numer faktury, nazwa, cena, jakość) VALUES (": num", " <xsl:value-of select="name" />", "<xsl:value-of select="price" />", "<xsl:value-of select="quality" /> ") </xsl:for-each> </xsl:template> </xsl:stylesheet> </p><p>Wyjaśniając powyższy przykład, należy zauważyć, że użycie pary tagów ma charakter formalny, ponieważ po przeanalizowaniu wynikowy dokument XML musi formalnie zawierać co najmniej jeden węzeł. Metoda ResultDoc.text przypisuje wartość tekstową ResultDoc uzyskaną podczas analizowania dokumentu XML. W tym przypadku wartością jest wszystko, co jest otoczone parą tagów i np. wygenerowane przez nas zapytanie SQL.</p> <p>Na kolejną cechę pisania programu należy zwrócić uwagę na możliwość wykorzystania parametru SQL <b>: num.</b> Użycie parametru upraszcza tekst szablonu xsl. Definicja wartości odpowiednich elementów węzłów dokumentu XML jest określana początkowo przez wybór według nazwy odpowiedniego węzła, na przykład:</p><h2>XSL w skrócie</h2> <p>XSL to akronim wywodzący się z eXtensible Stylesheet Language, języka formatowania arkuszy stylów (dane XML). Jak widać z nagłówka, do formatowania danych XML używany jest język eXtensible Stylesheet Language (XSL). Z definicji W3C XSL składa się z dwóch części:</p> <ul><li>XSLT - transformacja XSL. Język używany do przekształcania lub formatowania (przekształcania) dokumentów XML. W ten sposób, używając XSLT, możemy uzyskać różne sekcje zestawu danych oraz formy prezentacji danych.</li><li>Formatowanie elementów. Elementy te obejmują wszystkie typograficzne elementy danych, po przetworzeniu ich za pomocą XSL. Używany tylko do generowania stron HTML.</li> </ul><p>Z pomocą XSLT możemy wybrać potrzebne nam dane z pliku XML i ułożyć je w formie do prezentacji użytkownikowi. Na przykład w naszym przypadku przekształciliśmy dane XML w postaci zapytania SQL. Klasycznym zastosowaniem XSL jest zwykle formatowanie danych w postaci stron HTML lub rzadziej w postaci plików RTF.</p> <p>Plik XSL opisuje szablon, według którego zostanie przeprowadzona transformacja danych XML. Wracając do szablonów xsl, w XSLT można wyróżnić następujące elementy (dyrektywy):</p> <table cellspacing="0" cellpadding="4" width="500" border="1"><tbody><tr><td valign="top" width="31%"> <b>Dyrektywy XSL</b> </td><th align="middle" width="69%"> <b>opis</b> </th> </tr><tr><td>xsl: Apply-templates</td> <td>Dyrektywa wskazująca użycie pasujących szablonów dla wybranego atrybutu \u003d „nazwa szablonu”</td> </tr><tr><td>xsl: atrybut</td> <td>tworzy drzewo atrybutów i dodaje je do elementu wyjściowego, nazwa parametru \u003d "nazwa atrybutu", przestrzeń nazw to URI przestrzeni nazw (prefiks przestrzeni nazw)</td> </tr><tr><td>xsl: szablon wezwania</td> <td>wywołuje szablon, nazwa atrybutu \u003d "URI do szablonu"</td> </tr><tr><td>xsl: wybierz <br>xsl: kiedy <br>xsl: w przeciwnym razie</td> <td>selekcja według warunku xsl: when expr \u003d "ocena wyrażenia w skrypcie", <br>język \u003d "nazwa-języka" <br>test \u003d "ocenione wyrażenie"</td> </tr><tr><td>xsl: komentarz</td> <td>generuje komentarz w dokumencie wyjściowym</td> </tr><tr><td>xsl: kopiuj <br>xsl: copy-of</td> <td>kopiuje bieżący węzeł do źródła wyjściowego lub wstawia fragment dokumentu do węzła, w którym atrybut select \u003d „nazwa węzła źródłowego”</td> </tr><tr><td>xsl: element</td> <td>tworzy element wyjściowy według nazwy, nazwa atrybutu \u003d "nazwa elementu", namespace \u003d "odwołanie do przestrzeni nazw uri"</td> </tr><tr><td>xsl: for-each</td> <td>ponownie stosuje szablon do wszystkich węzłów na liście węzłów, atrybut select określa listę węzłów</td> </tr><tr><td>xsl: jeśli</td> <td>sprawdzanie stanu, ustawiane przez atrybut test jako wyrażenie</td> </tr><tr><td>xsl: include</td> <td>zawiera szablon zewnętrzny, atrybut href \u003d "odniesienie URI"</td> </tr><tr><td>xsl: wyjście</td> <td>określa wyjście, atrybut metody może mieć wartość „xml”, „html” lub „text”</td> </tr><tr><td>xsl: param</td> <td>określa wartość parametrów, nazwa atrybutu \u003d "nazwa parametru", select \u003d "wartość"</td> </tr><tr><td>xsl: instrukcja-przetwarzania</td> <td>tworzy instrukcję przetwarzania, nazwa atrybutu \u003d "nazwa procesu instrukcji"</td> </tr><tr><td>xsl: sort</td> <td>sortuje zbiór węzłów, atrybuty select \u003d "nazwa węzła", typ danych \u003d typ danych ("tekst" | "liczba" | nazwa Q), kolejność \u003d kierunek sortowania ("rosnąco" | "malejąco")</td> </tr><tr><td>xsl: arkusz stylów</td> <td>definiuje dokument szablonu xsl, jest elementem głównym XSLT</td> </tr><tr><td>xsl: szablon</td> <td>definiuje xsl-template, nazwa atrybutu \u003d "prefiks URI do nazwy szablonu", match \u003d "wskazanie węzła, do którego szablon jest zastosowany"</td> </tr><tr><td>xsl: tekst</td> <td>generuje tekst do strumienia wyjściowego, atrybut disable-output-escaping \u003d "tak" lub "nie", wskazuje na możliwość generowania znaków ESC</td> </tr><tr><td>xsl: wartość-of</td> <td>wstawia wartość wybranego węzła jako tekst, atrybut select \u003d "wskaźnik do węzła", z którego pobierana jest wartość</td> </tr><tr><td>xsl: zmienna</td> <td>określa wartość granic zmiennej, nazwa atrybutu \u003d "nazwa zmiennej", select \u003d "obliczanie wartości zmiennej"</td> </tr><tr><td>xsl: z-param</td> <td>stosuje parametr do szablonu, nazwa atrybutu \u003d "nazwa parametru", select \u003d wyrażenie do oceny bieżącego kontekstu, wartość domyślna "."</td> </tr></tbody></table><h2>Wniosek</h2> <p>Na koniec należy zauważyć, że przy użyciu standardowego parsera XML <i>msxml.dll</i>nie jest jedynym narzędziem do analizowania i tworzenia dokumentów XML. Na przykład, aby tworzyć dokumenty XML, efektywnie korzystaj z tych komponentów <b>TPageProduser</b>i <b>TableProduser</b>... Ale ten artykuł podkreśla tylko zakres i zastosowanie modelu DOM w praktyce.</p> <p>Autor będzie bardzo wdzięczny za Twoją opinię na temat trafności tematu, ogólnej treści, stylu prezentacji, a także wszelkie inne komentarze, które pomogą w dalszej poprawie jakości pisania zbioru artykułów i wydania książki na temat praktycznej strony wykorzystania dokumentów XML w handlu elektronicznym. Bardziej szczegółowe informacje na temat praktycznej strony korzystania z dokumentów elektronicznych można znaleźć na stronie autora www.eDocs.al.ru. Planowane jest również umieszczenie tekstów źródłowych i przykładów na stronie autora.</p> <p>XML jest coraz częściej używany do przechowywania informacji i wymiany ich między aplikacjami i witrynami sieci Web. Wiele aplikacji używa tego języka jako języka bazowego do przechowywania danych, podczas gdy inne używają go do eksportowania i importowania danych XML. Czas więc, aby programiści zastanowili się, jak dane XML można wykorzystać we własnych aplikacjach.</p> <p>W tym artykule przyjrzymy się XML Document Object Model (DOM) i implementacji XML DOM firmy Microsoft.</p> <p>XML DOM to model obiektowy, który zapewnia programiście obiekty do ładowania i przetwarzania plików XML. Model obiektowy składa się z następujących podstawowych obiektów: XMLDOMDocument, XMLDOMNodeList, XMLDOMNode, XMLDOMNamedNodeMap i XMLDOMParseError. Każdy z tych obiektów (z wyjątkiem XMLDOMParseError) zawiera właściwości i metody, które pozwalają uzyskać informacje o obiekcie, manipulować wartościami i strukturą obiektu oraz nawigować po strukturze dokumentu XML.</p> <p>Spójrzmy na główne obiekty XML DOM i pokażmy kilka przykładów ich użycia w Borland Delphi.</p> <h2> Korzystanie z XML DOM w Borland Delphi</h2> <p>Aby korzystać z Microsoft XML DOM w aplikacjach Delphi, należy podłączyć do projektu odpowiednią bibliotekę typów. W tym celu wykonujemy polecenie Projekt | Biblioteka typów importu i w oknie dialogowym Biblioteka typów importu wybierz bibliotekę Microsoft XML w wersji 2.0 (wersja 2.0), która zwykle znajduje się w pliku Windows \\ System \\ MSXML.DLL</p> <p>Po kliknięciu przycisku Utwórz jednostkę zostanie utworzony moduł interfejsu MSXML_TLB, który pozwoli nam korzystać z obiektów XML DOM: DOMDocument, XMLDocument, XMLHTTPRequest i wielu innych zaimplementowanych w bibliotece MSXML.DLL. Odniesienie do modułu MSXML_TLB musi znajdować się na liście Zastosowania.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Urządzenie XML DOM</h2> <p>Model obiektu dokumentu przedstawia dokument XML jako strukturę drzewa gałęzi. Interfejsy API XML DOM umożliwiają aplikacjom poruszanie się po drzewie dokumentu i manipulowanie jego gałęziami. Każda gałąź może mieć określony typ (DOMNodeType), zgodnie z którym określa się gałąź nadrzędną i podrzędną. Większość dokumentów XML zawiera gałęzie typu element, atrybut i tekst. Atrybuty to specjalny rodzaj gałęzi i nie są to gałęzie podrzędne. Atrybuty są przetwarzane za pomocą specjalnych metod dostarczanych przez obiekty XML DOM.</p> <p>Oprócz implementacji interfejsów zalecanych przez World Wide Web Consortium (W3C), Microsoft XML DOM zawiera metody obsługujące XSL, wzorce XSL, przestrzenie nazw i typy danych. Na przykład metoda SelectNodes umożliwia użycie składni wzorca XSL do znajdowania gałęzi w określonym kontekście, a metoda TransformNode obsługuje używanie XSL do wykonywania przekształceń.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Testowy dokument XML</h2> <p>Jako przykładowy dokument XML weźmy katalog z muzyką na dysku CD-ROM, który ma następującą strukturę:</p><p> <?xml version=”1.0"?> <CATALOG> <CD> <TITLE>Burleska imperium Bob Dylan USA Columbia 10.90 1985 Ukryj swoje serce Bonnie tylor UK CBS Records 9.90 1988 ... Uwolnij moje serce Joe cocker USA EMI 8.20 1987

Jesteśmy teraz gotowi, aby zacząć przyglądać się modelowi obiektowemu XML DOM, zaczynając od obiektu XMLDOMDocument.

Dokument XML - obiekt XMLDOMDocument

Praca z dokumentem XML zaczyna się od załadowania go. W tym celu używamy metody Load, która ma tylko jeden parametr określający adres URL załadowanego dokumentu. Podczas ładowania plików z dysku lokalnego podawana jest tylko pełna nazwa pliku (w tym przypadku można pominąć protokół file: ///). Jeśli dokument XML jest przechowywany jako ciąg, użyj metody LoadXML, aby załadować ten dokument.

Właściwość Async służy do kontrolowania sposobu ładowania dokumentu (synchronicznego lub asynchronicznego). Domyślnie ta właściwość ma wartość True, co oznacza, że \u200b\u200bdokument jest ładowany asynchronicznie, a sterowanie jest zwracane do aplikacji przed pełnym załadowaniem dokumentu. W przeciwnym razie dokument ładuje się synchronicznie, a następnie musisz sprawdzić wartość właściwości ReadyState, aby zobaczyć, czy dokument został załadowany, czy nie. Można również utworzyć procedurę obsługi dla zdarzenia OnReadyStateChange, która przejmie kontrolę po zmianie wartości właściwości ReadyState.

Poniżej pokazano, jak załadować dokument XML za pomocą metody Load:

Używa ... MSXML_TLB ... procedure TForm1.Button1Click (Sender: TObject); var XMLDoc: IXMLDOMDocument; begin XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // // Tutaj kod // manipuluje dokumentem XML i jego gałęziami // XMLDoc: \u003d Nil; koniec;

Po załadowaniu dokumentu mamy dostęp do jego właściwości. Zatem właściwość NodeName będzie zawierała wartość #document, właściwość NodeTypeString będzie zawierała wartość dokumentu, a właściwość URL będzie zawierała wartość file: /// C: /DATA/DATA.xml.

Obsługa błędów

Szczególnie interesujące są właściwości związane z przetwarzaniem dokumentu podczas jego ładowania. Na przykład właściwość ParseError zwraca obiekt XMLDOMParseError zawierający informacje o błędzie, który wystąpił podczas przetwarzania dokumentu.

Aby napisać procedurę obsługi błędów, możesz dodać następujący kod:

Var XMLError: IXMLDOMParseError; ... XMLDoc.Load („C: \\ DATA \\ DATA.xml”); XMLError: \u003d XMLDoc.ParseError; Jeśli XMLError.ErrorCode<> 0 Wtedy // // Tutaj zajmiemy się błędem // Else Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: \u003d Nil;

Aby zobaczyć, jakie informacje są zwracane w przypadku błędu, zmień następujący wpis katalogu:

Burleska imperium Bob Dylan USA Columbia 10.90 1985

usunięcie elementu zamykającego w drugiej linii:</p><p> <CD> <TITLE>Burleska imperium <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> </p><p>Teraz napiszmy kod, który zwraca wartości właściwości obiektu XMLDOMParseError:</p><p>XMLError: \u003d XMLDoc.ParseError; Jeśli XMLError.ErrorCode<> 0 Następnie z XMLError, Memo1.Lines zaczyna się Dodaj („Plik:” + URL); Add („Code:” + IntToStr (ErrorCode)); Dodaj („Błąd:” + przyczyna); Dodaj („Text:” + SrcText); Dodaj („Line:” + IntToStr (Line)); Dodaj („Stanowisko:” + IntToStr (LinePos)); koniec Else Memo1.Lines.Add (XMLDoc.XML); Koniec;</p><p>i uruchom naszą aplikację. W rezultacie otrzymujemy następujące informacje o błędzie.</p> <p>Jak widać z powyższego przykładu, informacje zwracane przez obiekt XMLDOMParseError są wystarczające do zlokalizowania błędu i zrozumienia przyczyny jego wystąpienia.</p> <p>Teraz przywrócimy element zamykający <TITLE> w naszym dokumencie i kontynuuj dyskusję na temat XML DOM.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Dostęp do drzewa dokumentów</h2> <p>Aby uzyskać dostęp do drzewa dokumentu, możesz pobrać element główny, a następnie powtórzyć jego gałęzie podrzędne lub znaleźć określoną gałąź. W pierwszym przypadku element główny uzyskujemy poprzez właściwość DocumentElement, która zwraca obiekt typu XMLDOMNode. Oto jak użyć właściwości DocumentElement, aby pobrać zawartość każdego elementu podrzędnego:</p><p>Węzeł Var: IXMLDOMNode; Root: IXMLDOMElement; I: Integer; ... Root: \u003d XMLDoc.DocumentElement; Dla I: \u003d 0 do Root.ChildNodes.Length-1 do Begin Node: \u003d Root.ChildNodes.Item [I]; Memo1.Lines.Add (Node.Text); Koniec;</p><p>W przypadku naszego dokumentu XML otrzymujemy następujący tekst.</p> <p>Jeśli interesuje nas konkretna gałąź lub gałąź poniżej pierwszej gałęzi podrzędnej, możemy użyć metody NodeFromID lub metody GetElementByTagName obiektu XMLDOMDocument.</p> <p>Metoda NodeFromID wymaga unikatowego identyfikatora zdefiniowanego w schemacie XML lub definicji typu dokumentu (DTD) i zwraca gałąź z tym identyfikatorem.</p> <p>Metoda GetElementByTagName wymaga ciągu znaków z określonym elementem (tagiem) i zwraca wszystkie gałęzie z tym elementem. Oto jak użyć tej metody, aby znaleźć wszystkich artystów w naszym katalogu na CD-ROM:</p><p>Węzły: IXMLDOMNodeList; Węzeł: IXMLDOMNode; ... Węzły: \u003d XMLDoc.GetElementsByTagName („ARTIST”); Dla I: \u003d 0 do Nodes.Length-1 do Begin Node: \u003d Nodes.Item [I]; Memo1.Lines.Add (Node.Text); Koniec;</p><p>Dla naszego dokumentu XML otrzymamy następujący tekst</p> <p>Należy zauważyć, że metoda SelectNodes obiektu XMLDOMNode zapewnia bardziej elastyczny sposób uzyskiwania dostępu do gałęzi dokumentu. Ale więcej na ten temat poniżej.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Gałąź dokumentu - obiekt XMLDOMNode</h2> <p>Obiekt XMLDOMNode reprezentuje gałąź dokumentu. Napotkaliśmy już ten obiekt podczas pobierania elementu głównego dokumentu:</p><p>Root: \u003d XMLDoc.DocumentElement;</p><p>Aby uzyskać informacje o gałęzi dokumentu XML, możesz skorzystać z właściwości obiektu XMLDOMNode (Tabela 1).</p> <p>Aby uzyskać dostęp do danych przechowywanych w gałęzi, często używa się właściwości NodeValue (dostępnej dla atrybutów, gałęzi tekstowych, komentarzy, instrukcji przetwarzania i sekcji CDATA) lub właściwości Text, która zwraca zawartość tekstową gałęzi, lub właściwości NodeTypedValue. Ta ostatnia może być jednak używana tylko dla oddziałów z wpisanymi elementami.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3> Poruszanie się po drzewie dokumentów</h3> <p>Obiekt XMLDOMNode zapewnia wiele sposobów poruszania się po drzewie dokumentu. Na przykład, aby uzyskać dostęp do gałęzi nadrzędnej, użyj właściwości ParentNode (typ XMLDOMNode), uzyskaj dostęp do gałęzi podrzędnych za pośrednictwem właściwości ChildNodes (typ XMLDOMNodeList), FirstChild i LastChild (typ XMLDOMNode) itp. Właściwość OwnerDocument zwraca obiekt XMLDOMDocument, który identyfikuje sam dokument XML. Właściwości wymienione powyżej ułatwiają nawigację po drzewie dokumentu.</p> <p>Przejdźmy teraz do wszystkich gałęzi dokumentu XML:</p><p>Root: \u003d XMLDoc.DocumentElement; Dla I: \u003d 0 do Root.ChildNodes.Length-1 do Begin Node: \u003d Root.ChildNodes.Item [I]; Jeśli Node.HasChildNodes Then GetChilds (Node, 0); Koniec;</p><p>Jak wspomniano powyżej, SelectNodes obiektu XMLDOMNode zapewnia bardziej elastyczny sposób dostępu do gałęzi dokumentu. Ponadto istnieje metoda SelectSingleNode, która zwraca tylko pierwszą gałąź dokumentu. Obie te metody umożliwiają definiowanie szablonów XSL do wyszukiwania oddziałów.</p> <p>Przyjrzyjmy się procesowi użycia metody SelectNodes do pobrania wszystkich gałęzi, które mają gałąź CD i podgałęzi PRICE:</p><p>Root: \u003d XMLDoc.DocumentElement; Węzły: \u003d Root.SelectNodes („CD / PRICE”);</p><p>Wszystkie podgałęzi PRICE gałęzi CD zostaną umieszczone w kolekcji Nodes. Wrócimy nieco później do omówienia szablonów XSL.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h3> Manipulowanie gałęziami potomnymi</h3> <p>Do manipulowania gałęziami potomnymi możemy wykorzystać metody obiektu XMLDOMNode (Tabela 2).</p> <p>Aby całkowicie usunąć zapis dotyczący pierwszego dysku, należy uruchomić następujący kod:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // Pobierz element główny Root: \u003d XMLDoc.DocumentElement; Węzeł: \u003d Root; // Usuń pierwszą gałąź podrzędną Node.RemoveChild (Node.FirstChild);</p><p>Zauważ, że w tym przykładzie usuwamy pierwszą gałąź podrzędną. Sposób usunięcia pierwszego elementu z pierwszej gałęzi podrzędnej pokazano poniżej:</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.Load („C: \\ DATA \\ DATA.xml”); // Pobierz element główny Root: \u003d XMLDoc.DocumentElement; // i pierwsza gałąź podrzędna Node: \u003d Root.FirstChild; // Usuń pierwszą gałąź podrzędną Node.RemoveChild (Node.FirstChild);</p><p>W powyższym przykładzie usunęliśmy nie pierwszą gałąź <CD>…</CD>a pierwszym elementem tej gałęzi jest <TITLE>….

Teraz dodajmy nową gałąź. Poniżej znajduje się kod pokazujący, jak dodać nowy wpis na płycie CD z muzyką:

Var NewNode: IXMLDOMNode; Dziecko: IXMLDOMNode; ... // Utwórz nowy oddział - NewNode: \u003d XMLDoc.CreateNode (1, „CD”, „”); // Dodaj element Dziecko: \u003d XMLDoc.CreateNode (1, „TITLE”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘Pink Floyd’; // Dodaj element <ARTIST> Dziecko: \u003d XMLDoc.CreateNode (1, „ARTIST”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘Division Bell’; // Dodaj element <COUNTRY> Dziecko: \u003d XMLDoc.CreateNode (1, „KRAJ”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d „UK”; // Dodaj element <COMPANY> Dziecko: \u003d XMLDoc.CreateNode (1, „FIRMA”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d ‘EMI Records Ltd.’; // Dodaj element <PRICE>Dziecko: \u003d XMLDoc.CreateNode (1, „PRICE”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d '11 .99 "; // Dodaj element <YEAR> Dziecko: \u003d XMLDoc.CreateNode (1, „YEAR”, „”); // Dodaj element NewNode.AppendChild (Child); // I ustaw jego wartość Child.Text: \u003d „1994”; // I dodaj gałąź Root.AppendChild (NewNode); ...</p><p>Powyższy kod przedstawia następujące kroki, aby dodać nową gałąź:</p> <ul><li>Tworzenie nowej gałęzi za pomocą metody CreateNode: <ul><li>tworzenie elementu za pomocą metody CreateNode;</li> <li>dodanie elementu do gałęzi przy pomocy metody AppendChild;</li> <li>ustawienie wartości elementu poprzez właściwość Text;</li> <li>… Powtórz te czynności dla wszystkich elementów.</li> </ul></li> <li>Dodanie nowej gałęzi do dokumentu przy użyciu metody AppendChild.</li> </ul><p>Przypomnij sobie, że metoda AppendChild dodaje gałąź na końcu drzewa. Aby dodać gałąź w określone miejsce w drzewie należy skorzystać z metody InsertBefore.</p> <h2> Zestaw gałęzi - obiekt XMLDOMNodeList</h2> <p>Obiekt XMLNodeList zawiera listę gałęzi, które można zbudować za pomocą metod SelectNodes lub GetElementsByTagName, a także uzyskać z właściwości ChildNodes.</p> <p>Omówiliśmy już użycie tego obiektu w przykładzie przedstawionym w sekcji „Poruszanie się po drzewie dokumentu”. W tym miejscu przedstawimy kilka uwag teoretycznych.</p> <p>Liczbę gałęzi na liście można uzyskać jako wartość właściwości Długość. Gałęzie są indeksowane od 0 do Length-1, a każda pojedyncza gałąź jest dostępna poprzez odpowiedni indeksowany element w tablicy Item.</p> <p>Poruszanie się po liście oddziałów można również wykonać przy użyciu metody NextNode, która zwraca następną gałąź na liście lub Nil, jeśli bieżąca gałąź jest ostatnią. Aby powrócić na początek listy, wywołaj metodę Reset.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Twórz i zapisuj dokumenty</h2> <p>Widzieliśmy więc, jak można dodawać gałęzie i elementy do istniejących dokumentów XML. Teraz utwórzmy dokument XML w locie. Przede wszystkim pamiętaj, że dokument można załadować nie tylko z adresu URL, ale także ze zwykłego ciągu. Poniżej pokazano, jak utworzyć element główny, którego można następnie użyć do dynamicznego zbudowania pozostałych elementów (co zostało już omówione w sekcji „Manipulowanie gałęziami potomnymi”):</p><p>Var XMLDoc: IXMLDOMDocument; Root: IXMLDOMNode; Węzeł: IXMLDOMNode; S: WideString; ... S: \u003d „ <CATALOG></CATALOG>'; XMLDoc: \u003d CoDOMDocument.Create; XMLDoc.Async: \u003d False; XMLDoc.LoadXML (S); Root: \u003d XMLDoc.DocumentElement; Węzeł: \u003d XMLDoc.CreateNode (1, „CD”, „”); Root.AppendChild (węzeł); Memo1.Lines.Add (XMLDoc.XML); ... XMLDoc: \u003d Nil;</p><p>Po zbudowaniu dokumentu XML zapisz go do pliku przy użyciu metody Save. Na przykład:</p> <p>XMLDoc.Save ('C: \\ DATA \\ NEWCD.XML');</p> <p>Oprócz zapisywania do pliku metoda Save umożliwia zapisanie dokumentu XML w nowym obiekcie XMLDOMDocument. W takim przypadku dokument jest w pełni przetwarzany, w wyniku czego sprawdzana jest jego struktura i składnia. Oto jak zapisać dokument w innym obiekcie:</p><p>Procedura TForm1.Button2Click (Sender: TObject); var XMLDoc2: IXMLDOMDocument; rozpocznij XMLDoc2: \u003d CoDOMDocument.Create; XMLDoc.Save (XMLDoc2); Memo2.Lines.Add (XMLDoc2.XML); ... XMLDoc2: \u003d Nil; koniec;</p><p>Na koniec należy zauważyć, że metoda Save umożliwia również zapisanie dokumentu XML w innych obiektach COM, które obsługują interfejsy IStream, IPersistStream lub IPersistStreamInit.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Korzystanie z szablonów XSL</h2> <p>Omawiając metodę SelectNodes obiektu XMLDOMNode, wspomnieliśmy, że zapewnia ona bardziej elastyczny sposób dostępu do gałęzi dokumentu. Elastyczność polega na tym, że można określić szablon XSL jako kryterium wyboru oddziałów. Takie szablony zapewniają potężny mechanizm wyszukiwania informacji w dokumentach XML. Na przykład, aby uzyskać listę wszystkich tytułów muzycznych CD-ROM w naszym katalogu, możesz uruchomić następujące zapytanie:</p><p>Aby dowiedzieć się, które płyty artystów zostały wydane w USA, prośba jest sformułowana w następujący sposób:</p><p>Węzły: \u003d Root.SelectNodes („CD / ARTIST”);</p><p>Oto jak znaleźć pierwszy dysk w katalogu:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>i ostatni:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>Aby znaleźć dyski Boba Dylana, możesz uruchomić następujące zapytanie:</p><p>Węzły: \u003d Root.SelectNodes („CD [$ any $ ARTIST \u003d” Bob Dylan ”] / TITLE”);</p><p>i aby uzyskać listę dysków wykonanych po 1985 roku, uruchamiamy następujące zapytanie:</p><p>Węzły: \u003d Root.SelectNodes („CD / TITLE”);</p><p>Bardziej szczegółowe omówienie składni XSL wymaga osobnej publikacji. Aby zaintrygować czytelników i zachęcić do dalszych badań, podam tylko jeden mały przykład możliwego wykorzystania XSL. Powiedzmy, że musimy przekonwertować nasz katalog na zwykłą tabelę HTML. Używając tradycyjnych metod, musimy iterować po wszystkich gałęziach drzewa i dla każdego otrzymanego elementu tworzyć odpowiednie tagi <TD>…</TD>.</p> <p>Używając XSL, po prostu tworzymy szablon (lub arkusz stylów), który określa, co i jak przekształcić. Następnie umieszczamy ten szablon w naszym katalogu - i to wszystko: mamy tekst szablonu XSL, który przekształca katalog w tabelę (Listing 2).</p> <p>Kod nakładający szablon XSL na nasz katalog wygląda następująco:</p><p>Procedura TForm1.Button2Click (Sender: TObject); var XSLDoc: IXMLDOMDocument; begin XSLDoc: \u003d CoDOMDocument.Create; XSLDoc.Load („C: \\ DATA \\ DATA.xsl”); Memo2.Text: \u003d XMLDoc.TransformNode (XSLDoc); XSLDoc: \u003d Nil; koniec;</p><p>Kończąc naszą dyskusję o XSL, należy stwierdzić, że obecnie język ten jest aktywnie używany do transformacji między różnymi dokumentami XML, a także do formatowania dokumentów.</p> <table border="0" width="100%"><tr><td width="50%"> </td> <td width="50%"> </td> </tr></table><h2> Wniosek</h2> <p>Z oczywistych powodów niemożliwe jest omówienie wszystkich obiektów Microsoft XML DOM i podanie przykładów ich użycia w jednym artykule. Tutaj właśnie poruszyliśmy podstawowe kwestie związane z wykorzystaniem XML DOM w aplikacjach. Stół 3 pokazuje wszystkie obiekty zaimplementowane w Microsoft XML DOM.</p> <p>ComputerPress 12 "2000</p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy>");</script> </div> <div class="bsb-wrap bsb-bold bsb-after-post php-mode" data-post-id="4848" data-share-url="/eshhe-odin-nalog-chem-zamenit-nalog-na-modernizatsiyu/"> <div class="bsb-items"> <div class="bsb-item bsb-facebook bsb-no-count" data-id="facebook"> <a href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fqipu.ru%2Fpl%2Fmts%2Fispolzovanie-xml-v-srede-delphi-ispolzovanie-xml-document-object-model.html" class="bsb-link" target="_blank" data-wpel-link="internal"> <i class="bsb-icon icon icon-facebook"></i> <span class="bsb-label">Dzielić</span> </a> </div> <div class="bsb-item bsb-telegram bsb-no-count" data-id="telegram"> <a href="https://qipu.ru/pl/tg://msg?text=https%3A%2F%2Fqipu.ru%2Fmts%2Fispolzovanie-xml-v-srede-delphi-ispolzovanie-xml-document-object-model.html" class="bsb-link" target="_blank" data-wpel-link="internal"> <i class="bsb-icon icon icon-telegram"></i> <span class="bsb-label">Dzielić</span> </a> </div> <div class="bsb-item bsb-twitter bsb-no-count" data-id="twitter"> <a href="https://twitter.com/share?url=https%3A%2F%2Fqipu.ru%2Fpl%2Fmts%2Fispolzovanie-xml-v-srede-delphi-ispolzovanie-xml-document-object-model.html" class="bsb-link" target="_blank" data-wpel-link="internal"> <i class="bsb-icon icon icon-twitter"></i> <span class="bsb-label">Ćwierkać</span> </a> </div> <div class="bsb-item bsb-vkontakte bsb-no-count" data-id="vkontakte"> <a href="https://vk.com/share.php?url=https%3A%2F%2Fqipu.ru%2Fmts%2Fispolzovanie-xml-v-srede-delphi-ispolzovanie-xml-document-object-model.html" class="bsb-link" target="_blank" data-wpel-link="internal"> <i class="bsb-icon icon icon-vkontakte"></i> <span class="bsb-label">Lubić</span> </a> </div> <div class="bsb-item bsb-fb-messenger bsb-no-count" data-id="fb-messenger"> <a href="https://qipu.ru/pl/fb-messenger://share/?link=https%3A%2F%2Fqipu.ru%2Fmts%2Fispolzovanie-xml-v-srede-delphi-ispolzovanie-xml-document-object-model.html" class="bsb-link" target="_blank" data-wpel-link="internal"> <i class="bsb-icon icon icon-fb-messenger"></i> <span class="bsb-label">Lubić</span> </a> </div> </div> </div> </div> </div> </article> <section class="section-carousel"> <div class="post-carousel"> <h3 class="title-block">Przeczytaj także</h3> <div class="owl-container owl-loop" data-columns="3" data-padding="20"> <div class="owl-carousel"> <article class="post- post type-post status-publish format-standard has-post-thumbnail hentry category-morning-news"> <div class="post-thumbnail"> <img width="720" height="378" src="/uploads/21bdb89907abffe2b99c0b5b23f46545.jpg" class="attachment-md size-md wp-post-image" alt="Jakie rozszerzenie mają pliki aplikacji na iOS?" / loading=lazy> <div class="post-more"><a href="https://qipu.ru/pl/megafon/rasshirenie-prilozhenii-dlya-iphone-kakoe-rasshirenie-imeyut-faily.html" class="btn-link" data-wpel-link="internal"><span>Czytać</span></a></div> <ul class="post-meta"></ul> <a href="https://qipu.ru/pl/megafon/rasshirenie-prilozhenii-dlya-iphone-kakoe-rasshirenie-imeyut-faily.html" data-wpel-link="internal"></a> </div> <h2 class="entry-title"><a href="https://qipu.ru/pl/megafon/rasshirenie-prilozhenii-dlya-iphone-kakoe-rasshirenie-imeyut-faily.html" data-wpel-link="internal">Jakie rozszerzenie mają pliki aplikacji na iOS?</a></h2> <ul class="post-meta"> <li class="meta-date"> <time class="entry-date published updated" datetime=""> 13.08.2020 </time> </li> </ul> </article> <!-- /next_post --> <article class="post- post type-post status-publish format-standard has-post-thumbnail hentry category-morning-news"> <div class="post-thumbnail"> <img width="720" height="378" src="/uploads/95e52a248bd0f4939d9ea107b8b342e2.jpg" class="attachment-md size-md wp-post-image" alt="Jak otwierać archiwa ZIP na iPhonie" / loading=lazy> <div class="post-more"><a href="https://qipu.ru/pl/megafon/papka-faily-na-aifone-kak-otkryvat-zip-arhivy-na-iphone-kak-skinut.html" class="btn-link" data-wpel-link="internal"><span>Czytać</span></a></div> <ul class="post-meta"></ul> <a href="https://qipu.ru/pl/megafon/papka-faily-na-aifone-kak-otkryvat-zip-arhivy-na-iphone-kak-skinut.html" data-wpel-link="internal"></a> </div> <h2 class="entry-title"><a href="https://qipu.ru/pl/megafon/papka-faily-na-aifone-kak-otkryvat-zip-arhivy-na-iphone-kak-skinut.html" data-wpel-link="internal">Jak otwierać archiwa ZIP na iPhonie</a></h2> <ul class="post-meta"> <li class="meta-date"> <time class="entry-date published updated" datetime=""> 13.08.2020 </time> </li> </ul> </article> <!-- /next_post --> <article class="post- post type-post status-publish format-standard has-post-thumbnail hentry category-morning-news"> <div class="post-thumbnail"> <img width="720" height="378" src="/uploads/887ddd47ad4e0418a9861c79196d2741.jpg" class="attachment-md size-md wp-post-image" alt="Co to jest dostęp prywatny do komputera w przeglądarce Safari" / loading=lazy> <div class="post-more"><a href="https://qipu.ru/pl/bilajjn/kak-bystro-vklyuchit-ili-otklyuchit-chastnyi-dostup-v-safari-chto-takoe-chastnyi.html" class="btn-link" data-wpel-link="internal"><span>Czytać</span></a></div> <ul class="post-meta"></ul> <a href="https://qipu.ru/pl/bilajjn/kak-bystro-vklyuchit-ili-otklyuchit-chastnyi-dostup-v-safari-chto-takoe-chastnyi.html" data-wpel-link="internal"></a> </div> <h2 class="entry-title"><a href="https://qipu.ru/pl/bilajjn/kak-bystro-vklyuchit-ili-otklyuchit-chastnyi-dostup-v-safari-chto-takoe-chastnyi.html" data-wpel-link="internal">Co to jest dostęp prywatny do komputera w przeglądarce Safari</a></h2> <ul class="post-meta"> <li class="meta-date"> <time class="entry-date published updated" datetime=""> 13.08.2020 </time> </li> </ul> </article> <!-- /next_post --> </div> <div class="owl-dots"></div> </div> </div> </section> </main> </div> </div> </div> </div> <footer class="site-footer"> <style> .footer-section { width: 830px; margin: 0 auto; padding: 0; font-family: 'Noto Sans', sans-serif; } .site-footer { background-color: #222; } @media (max-width: 1025px) { .footer-section { max-width: 690px; } } @media (max-width: 760px) { .footer-section { width: 90%; } } .site-footer a:hover { color: #FF3400; } .white-a { color: #969696!important; } .white-a:hover { color: #fff!important; } .white-a:hover g { opacity: 1; } </style> <div class="footer-section"> <div class="footer" > <div class="footer__menu"> <div class="footer__menu__logo" style="background:none;"><img src="/logo.png" loading=lazy></div> <ul> <li><a href="https://qipu.ru/pl/category/bilajjn/">Linia powietrzna</a></li> <li><a href="https://qipu.ru/pl/category/megafon/">Megafon</a></li> <li><a href="https://qipu.ru/pl/category/mobilnye-sovety/">Porady dotyczące telefonów komórkowych</a></li> <li><a href="https://qipu.ru/pl/category/mts/">Mts</a></li> </ul> <ul> <li><a href="https://qipu.ru/pl/category/tele2/">TELE 2</a></li> <li><a href="https://qipu.ru/pl/category/yota/">Yota</a></li> <li><a href="https://qipu.ru/pl/category/bilajjn/">Linia powietrzna</a></li> <li><a href="https://qipu.ru/pl/category/megafon/">Megafon</a></li> </ul> </div> <div class="footer__social"> <a href="https://facebook.com/" target="_blank" class="footer__social--facebook white-a" data-wpel-link="external"></a> <a href="https://twitter.com/" target="_blank" class="footer__social--tw white-a" data-wpel-link="external"></a> <a href="" target="_blank" class="footer__social--vk white-a" data-wpel-link="external"></a> <a href="https://youtube.com/" target="_blank" class="footer__social--yt white-a" data-wpel-link="external"></a> </div> <div class="footer__info" > <p>© qipu.ru, 2020. Osobisty asystent w świecie komunikacji komórkowej <br> .</p> </div> </div> </div> </footer> </div> </div> <a href="https://qipu.ru/pl/#top" class="scroll-to-top hidden-sm-down" data-wpel-link="internal"></a> <div class="site-search" id="search"> <button type="button" class="close"></button> <div class="form-container"> <div class="container"> <div class="row"> <div class="col-lg-6 offset-lg-3"> <form role="search" method="get" class="search-form form" action="/"> <label class="sr-only">Szukaj:</label> <div class="input-group"> <input type="search" value="" name="s" class="search-field form-control" placeholder="Czego szukasz?" required> <span class="input-group-btn"> <button type="submit" class="search-submit btn btn-primary btn-effect"><span>Szukaj</span><span><i class="icon icon-search"></i></span></button> </span> </div> </form> <p>Wprowadź słowa kluczowe.</p> </div> </div> </div> </div> </div> <style type="text/css"> .wpmchimpa-overlay-bg.wpmchimpselector { display: none; top: 0; left: 0; height:100%; width: 100%; cursor: pointer; z-index: 999999; background: #000; background: rgba(0,0,0,0.40); background:rgba(0,0,0,0.7);cursor: default; position: fixed!important; } .wpmchimpa-overlay-bg #wpmchimpa-main *{ transition: all 0.5s ease; } .wpmchimpa-overlay-bg .wpmchimpa-mainc, .wpmchimpa-overlay-bg .wpmchimpa-maina{ -webkit-transform: translate(0,0); height:100%;} .wpmchimpa-overlay-bg #wpmchimpa-main { position: absolute; top: 50%; left: 50%; border-radius: 2px; -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); width: calc(100% - 20px); max-width:650px; background: #27313B; text-align: center; background-color:#ffffff;} #wpmchimpa-main #wpmchimpa-newsletterform{ } #wpmchimpa-main #wpmchimpa{ width: calc(100% - 20px); max-width: 400px; margin: 0 auto; } #wpmchimpa div{ position:relative; } #wpmchimpa h3{ line-height: 24px; margin-top:20px; color: #F4233C; font-size: 24px; font-family:Tahoma, Geneva, sans-serif;font-size:35px;line-height:35px;font-weight:normal;font-style:normal;color:#f34b38;} #wpmchimpa .wpmchimpa_para{ margin-top: 15px; } #wpmchimpa .wpmchimpa_para,#wpmchimpa .wpmchimpa_para * { font-size: 15px; color: #959595; font-family:Tahoma, Geneva, sans-serif;font-size:15px;} #wpmchimpa form{ margin: 20px auto; } #wpmchimpa .formbox > div:first-of-type{ width: 65%; float: left; } #wpmchimpa .formbox > div:first-of-type + div{ width: 35%; float: left; text-align: center; } #wpmchimpa .formbox input[type="text"]{ border-radius: 3px 0 0 3px; } #wpmchimpa .wpmchimpa-field{ position: relative; width:100%; margin: 0 auto 10px auto; text-align: left; } #wpmchimpa .inputicon{ display: none; } #wpmchimpa .wpmc-ficon .inputicon { display: block; width: 40px; height: 40px; position: absolute; top: 0; left: 0; pointer-events: none; } #wpmchimpa .wpmc-ficon input[type="text"], #wpmchimpa .wpmc-ficon input[type="text"] ~ .inputlabel{ padding-left: 40px; } #wpmchimpa .wpmc-ficon [wpmcfield="email"] ~ .inputicon { background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMzZDNkM2QiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTUxMiwzODRjMCwxMS4yMTktMy4xNTYsMjEuNjI1LTguMjE5LDMwLjc4MUwzNDIuMTI1LDIzMy45MDZMNTAyLjAzMSw5NGM2LjIxOSw5Ljg3NSw5Ljk2OSwyMS40NjksOS45NjksMzRWMzg0eiBNMjU2LDI2Ni43NUw0NzguNSw3Mi4wNjNjLTkuMTI1LTUtMTkuNDA2LTguMDYzLTMwLjUtOC4wNjNINjRjLTExLjEwOSwwLTIxLjM5MSwzLjA2My0zMC40ODQsOC4wNjNMMjU2LDI2Ni43NXogTTMxOC4wMzEsMjU0Ljk2OSBsLTUxLjUsNDUuMDk0QzI2My41MTYsMzAyLjY4OCwyNTkuNzY2LDMwNCwyNTYsMzA0cy03LjUxNi0xLjMxMy0xMC41MzEtMy45MzhsLTUxLjUxNi00NS4wOTRMMzAuMjUsNDM4LjE1NiBDNDAuMDYzLDQ0NC4zMTMsNTEuNTYzLDQ0OCw2NCw0NDhoMzg0YzEyLjQzOCwwLDIzLjkzOC0zLjY4OCwzMy43NS05Ljg0NEwzMTguMDMxLDI1NC45Njl6IE05Ljk2OSw5NEMzLjc1LDEwMy44NzUsMCwxMTUuNDY5LDAsMTI4IHYyNTZjMCwxMS4yMTksMy4xNDEsMjEuNjI1LDguMjE5LDMwLjc4MWwxNjEuNjQxLTE4MC45MDZMOS45NjksOTR6Ii8+PC9zdmc+') no-repeat center} #wpmchimpa .wpmc-ficon [wpmcfield="FNAME"] ~ .inputicon { background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMzZDNkM2QiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNjEyIDYxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjEyIDYxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBhdGggZD0iTTMwNi4wMDEsMzI1Ljk4OGM5MC41NjMtMC4wMDUsMTIzLjE0Ny05MC42ODIsMTMxLjY3OS0xNjUuMTY3QzQ0OC4xODgsNjkuMDYsNDA0Ljc5OSwwLDMwNi4wMDEsMCBjLTk4Ljc4MiwwLTE0Mi4xOTUsNjkuMDU1LTEzMS42NzksMTYwLjgyQzE4Mi44NjIsMjM1LjMwNCwyMTUuNDM2LDMyNS45OTUsMzA2LjAwMSwzMjUuOTg4eiIvPjxwYXRoIGQ9Ik01NTAuOTgxLDU0MS45MDhjLTAuOTktMjguOTA0LTQuMzc3LTU3LjkzOS05LjQyMS04Ni4zOTNjLTYuMTExLTM0LjQ2OS0xMy44ODktODUuMDAyLTQzLjk4My0xMDcuNDY1IGMtMTcuNDA0LTEyLjk4OC0zOS45NDEtMTcuMjQ5LTU5Ljg2NS0yNS4wODFjLTkuNjk3LTMuODEtMTguMzg0LTcuNTk0LTI2LjUzNy0xMS45MDFjLTI3LjUxOCwzMC4xNzYtNjMuNCw0NS45NjItMTA1LjE4Niw0NS45NjQgYy00MS43NzQsMC03Ny42NTItMTUuNzg2LTEwNS4xNjctNDUuOTY0Yy04LjE1Myw0LjMwOC0xNi44NCw4LjA5My0yNi41MzcsMTEuOTAxYy0xOS45MjQsNy44MzItNDIuNDYxLDEyLjA5Mi01OS44NjMsMjUuMDgxIGMtMzAuMDk2LDIyLjQ2My0zNy44NzMsNzIuOTk2LTQzLjk4MywxMDcuNDY1Yy01LjA0NSwyOC40NTQtOC40MzMsNTcuNDg5LTkuNDIyLDg2LjM5MwljLTAuNzY2LDIyLjM4NywxMC4yODgsMjUuNTI1LDI5LjAxNywzMi4yODRjMjMuNDUzLDguNDU4LDQ3LjY2NiwxNC43MzcsNzIuMDQxLDE5Ljg4NGM0Ny4wNzcsOS45NDEsOTUuNjAzLDE3LjU4MiwxNDMuOTIxLDE3LjkyNCBjNDguMzE4LTAuMzQzLDk2Ljg0NC03Ljk4MywxNDMuOTIxLTE3LjkyNGMyNC4zNzUtNS4xNDUsNDguNTktMTEuNDI0LDcyLjA0MS0xOS44ODQJQzU0MC42OTQsNTY3LjQzNSw1NTEuNzQ3LDU2NC4yOTcsNTUwLjk4MSw1NDEuOTA4eiIvPjwvZz48L3N2Zz4=') no-repeat center} #wpmchimpa .wpmc-ficon [wpmcfield="LNAME"] ~ .inputicon { background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMzZDNkM2QiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNjEyIDYxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjEyIDYxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBhdGggZD0iTTMwNi4wMDEsMzI1Ljk4OGM5MC41NjMtMC4wMDUsMTIzLjE0Ny05MC42ODIsMTMxLjY3OS0xNjUuMTY3QzQ0OC4xODgsNjkuMDYsNDA0Ljc5OSwwLDMwNi4wMDEsMCBjLTk4Ljc4MiwwLTE0Mi4xOTUsNjkuMDU1LTEzMS42NzksMTYwLjgyQzE4Mi44NjIsMjM1LjMwNCwyMTUuNDM2LDMyNS45OTUsMzA2LjAwMSwzMjUuOTg4eiIvPjxwYXRoIGQ9Ik01NTAuOTgxLDU0MS45MDhjLTAuOTktMjguOTA0LTQuMzc3LTU3LjkzOS05LjQyMS04Ni4zOTNjLTYuMTExLTM0LjQ2OS0xMy44ODktODUuMDAyLTQzLjk4My0xMDcuNDY1IGMtMTcuNDA0LTEyLjk4OC0zOS45NDEtMTcuMjQ5LTU5Ljg2NS0yNS4wODFjLTkuNjk3LTMuODEtMTguMzg0LTcuNTk0LTI2LjUzNy0xMS45MDFjLTI3LjUxOCwzMC4xNzYtNjMuNCw0NS45NjItMTA1LjE4Niw0NS45NjQgYy00MS43NzQsMC03Ny42NTItMTUuNzg2LTEwNS4xNjctNDUuOTY0Yy04LjE1Myw0LjMwOC0xNi44NCw4LjA5My0yNi41MzcsMTEuOTAxYy0xOS45MjQsNy44MzItNDIuNDYxLDEyLjA5Mi01OS44NjMsMjUuMDgxIGMtMzAuMDk2LDIyLjQ2My0zNy44NzMsNzIuOTk2LTQzLjk4MywxMDcuNDY1Yy01LjA0NSwyOC40NTQtOC40MzMsNTcuNDg5LTkuNDIyLDg2LjM5MwljLTAuNzY2LDIyLjM4NywxMC4yODgsMjUuNTI1LDI5LjAxNywzMi4yODRjMjMuNDUzLDguNDU4LDQ3LjY2NiwxNC43MzcsNzIuMDQxLDE5Ljg4NGM0Ny4wNzcsOS45NDEsOTUuNjAzLDE3LjU4MiwxNDMuOTIxLDE3LjkyNCBjNDguMzE4LTAuMzQzLDk2Ljg0NC03Ljk4MywxNDMuOTIxLTE3LjkyNGMyNC4zNzUtNS4xNDUsNDguNTktMTEuNDI0LDcyLjA0MS0xOS44ODQJQzU0MC42OTQsNTY3LjQzNSw1NTEuNzQ3LDU2NC4yOTcsNTUwLjk4MSw1NDEuOTA4eiIvPjwvZz48L3N2Zz4=') no-repeat center} #wpmchimpa .wpmchimpa-field textarea, #wpmchimpa .wpmchimpa-field select, #wpmchimpa input[type="text"]{ text-align: left; width: 100%; height: 40px; border-radius:3px; background: #fff; padding: 0 10px; color: #353535; font-size:17px; outline:0; display: block; border: 1px solid #efefef; font-family:Tahoma, Geneva, sans-serif;font-size:15px;color:#696565;} #wpmchimpa .wpmchimpa-field.wpmchimpa-multidrop select{ height: 100px; } #wpmchimpa .wpmchimpa-field.wpmchimpa-drop:before{ content: ''; width: 40px; height: 40px; position: absolute; right: 0; top: 0; pointer-events: none; background: no-repeat center; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMwMDAiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTZweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgOTQuODU5IDk0Ljg1OSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOTQuODU5IDk0Ljg1OSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTE3LjMxMiw0MS43NTdoNjAuMjM2YzAuNzcsMCwxLjQ2OS0wLjQ0LDEuODAyLTEuMTMzYzAuMzM0LTAuNjkxLDAuMjQxLTEuNTE0LTAuMjM3LTIuMTE0TDQ4Ljk5NCwwLjc1MyBDNDguNjE0LDAuMjc3LDQ4LjAzOSwwLDQ3LjQzMSwwcy0xLjE4NCwwLjI3Ny0xLjU2MywwLjc1M0wxNS43NDgsMzguNTFjLTAuNDc5LDAuNjAxLTAuNTcyLDEuNDIzLTAuMjM4LDIuMTE0IEMxNS44NDMsNDEuMzE3LDE2LjU0Miw0MS43NTcsMTcuMzEyLDQxLjc1N3oiLz4gPHBhdGggZD0iTTc3LjU0Nyw1My4xMDJIMTcuMzEyYy0wLjc2OSwwLTEuNDY5LDAuNDM5LTEuODAyLDEuMTMzYy0wLjMzNCwwLjY5MS0wLjI0MSwxLjUxNCwwLjIzOCwyLjExM2wzMC4xMTksMzcuNzU4IGMwLjM4LDAuNDc2LDAuOTU1LDAuNzUzLDEuNTYzLDAuNzUzczEuMTg0LTAuMjc3LDEuNTYzLTAuNzUzTDc5LjExLDU2LjM0OGMwLjQ3OS0wLjYwMSwwLjU3MS0xLjQyMiwwLjIzNy0yLjExMyBDNzkuMDE2LDUzLjU0MSw3OC4zMTcsNTMuMTAyLDc3LjU0Nyw1My4xMDJ6Ii8+PC9zdmc+'); } #wpmchimpa input[type="text"] ~ .inputlabel{ position: absolute; top: 0; left: 0; right: 0; pointer-events: none; width: 100%; line-height: 40px; color: rgba(0,0,0,0.6); font-size: 17px; font-weight:500; padding: 0 10px; white-space: nowrap; font-family:Tahoma, Geneva, sans-serif;font-size:15px;color:#696565;} #wpmchimpa input[type="text"]:valid + .inputlabel{ display: none; } #wpmchimpa select.wpmcerror, #wpmchimpa input[type="text"].wpmcerror{ border-color: red; } #wpmchimpa .wpmchimpa-check, #wpmchimpa .wpmchimpa-radio{ clear: both; } #wpmchimpa .wpmchimpa-check *, #wpmchimpa .wpmchimpa-radio *{ color: #fff; font-family:Tahoma, Geneva, sans-serif;font-size:14px;font-weight:normal;font-style:normal;color:#3d3d3d;} #wpmchimpa .wpmchimpa-item{ width:100%; display: inline-block; vertical-align: top; } #wpmchimpa .wpmchimpa-item input { display: none; } #wpmchimpa .wpmchimpa-item span { cursor: pointer; display: inline-block; position: relative; padding-left: 35px; line-height: 20px; margin-right: 10px; } #wpmchimpa .wpmchimpa-item span:before, #wpmchimpa .wpmchimpa-item span:after { content: ''; display: inline-block; width: 12px; height: 12px; left: 0; top: 4px; position: absolute; } #wpmchimpa .wpmchimpa-item span:before { border:1px solid #ccc; border-radius: 1px; background-color: #fff; -webkit-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; border: 1px solid#f34b38;background: #ffffff;} #wpmchimpa .wpmchimpa-item input[type='checkbox'] + span:hover:after, #wpmchimpa input[type='checkbox']:checked + span:after { content:''; width: 14px; height: 14px; background: no-repeat center; background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMwMDAwMDAiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDIzMCAyMzAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIzMCAyMzAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGQ9Ik05Mi4zNTYsMjIzLjU0OWM3LjQxLDcuNSwyMy45MTQsNS4wMTQsMjUuNjkxLTYuNzc5YzExLjA1Ni03My4yMTcsNjYuMzc4LTEzNC45ODUsMTA4LjI0My0xOTMuMTg5IEMyMzcuODk4LDcuNDUyLDIxMS4yMDctNy44NywxOTkuNzUsOC4wNjdDMTYxLjQ5Myw2MS4yNDksMTEzLjI3NCwxMTcuMjEsOTQuNDEsMTgxLjc0NCBjLTIxLjU1Ny0yMi4wMzEtNDMuMjAxLTQzLjg1My02Ny4zNzktNjMuMjEyYy0xNS4zMTItMTIuMjY1LTM3LjIxNSw5LjM0My0yMS43MzgsMjEuNzM3IEMzNi43OTQsMTY1LjUwMSw2NC4wMTcsMTk0LjkyNCw5Mi4zNTYsMjIzLjU0OXoiLz48L3N2Zz4='); } #wpmchimpa .wpmchimpa-item input[type='checkbox']:not(:checked) + span:hover:after { opacity: 0.5; } #wpmchimpa .wpmchimpa-item input[type='radio'] + span:before { border-radius: 50%; width: 12px; height: 12px; top: 4px; } #wpmchimpa input[type='radio']:checked + span:after { background: #000000; width: 8px; height: 8px; top: 6px; left: 2px; border-radius: 50%; } #wpmchimpa .wpmcinfierr{ display: block; height: 10px; text-align: left; line-height: 10px; margin-bottom: -10px; font-size: 10px; color: red; pointer-events: none; font-family:Tahoma, Geneva, sans-serif;} #wpmchimpa .wpmchimpa-subs-button{ border-radius: 0 3px 3px 0; width: 100%; color: #fff; font-size: 17px; border: 1px solid #FA0B38; background-color: #FF1F43; height: 40px; line-height: 40px; text-align: center; cursor: pointer; position: relative; top: 0; font-family:Tahoma, Geneva, sans-serif;font-size:16px;font-weight:normal;font-style:normal;color:#ffffff;background-color:#f34b38;} #wpmchimpa .wpmchimpa-subs-button::before{ content: 'Подписаться'; } #wpmchimpa .wpmchimpa-subs-button:hover{ background-color: #FA0B38; color:#ffffff;background-color:#75c462;} #wpmchimpa .wpmchimpa-subs-button.subsicon:before{ padding-left: 40px; } #wpmchimpa .wpmchimpa-subs-button.subsicon::after{ content:''; position: absolute; height: 40px; width: 40px; top: 0; left: 0; pointer-events: none; } .wpmchimpa-overlay-bg.signalshow .wpmchimpa-subs-button::after, .wpmchimpa-overlay-bg.signalshow .wpmchimpa-subs-button::before{ display: none; } #wpmchimpa-main .wpmchimpa-signal { display: none; z-index: 1; top: 5px; left: calc(50% - 20px); position: absolute; -webkit-transform: scale(0.8); -ms-transform: scale(0.8); transform: scale(0.8); } .wpmchimpa-overlay-bg.signalshow #wpmchimpa-main .wpmchimpa-signal { display: inline-block; } #wpmchimpa-main .wpmchimpa-feedback{ text-align: center; position: relative; color: #ccc; font-size: 10px; height: 12px; margin-top: -12px; font-family:Tahoma, Geneva, sans-serif;color:#3d3d3d;} #wpmchimpa-main .wpmchimpa-tag{ margin: 5px auto; } #wpmchimpa-main .wpmchimpa-tag, #wpmchimpa-main .wpmchimpa-tag *{ color:#fff; font-size: 10px; font-family:Tahoma, Geneva, sans-serif;font-size:10px;color:#3d3d3d;} #wpmchimpa-main .wpmchimpa-tag:before{ content:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMzZDNkM2QiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTBweCIgaGVpZ2h0PSIxMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTQxNy41NjYsMjA5LjgzaC05LjQ4NHYtNDQuMzg4YzAtODIuMDk5LTY1LjE1MS0xNTAuNjgxLTE0Ni41ODItMTUyLjE0NWMtMi4yMjQtMC4wNC02LjY3MS0wLjA0LTguODk1LDAgYy04MS40MzIsMS40NjQtMTQ2LjU4Miw3MC4wNDYtMTQ2LjU4MiwxNTIuMTQ1djQ0LjM4OGgtOS40ODVDODEuOTIyLDIwOS44Myw3MCwyMjQuOTEyLDcwLDI0My41Mzl2MjIyLjYzMiAgQzcwLDQ4NC43NzcsODEuOTIyLDUwMCw5Ni41MzksNTAwaDMyMS4wMjhjMTQuNjE3LDAsMjYuNTM5LTE1LjIyMywyNi41MzktMzMuODI5VjI0My41MzkgIEM0NDQuMTA1LDIyNC45MTIsNDMyLjE4NCwyMDkuODMsNDE3LjU2NiwyMDkuODN6IE0yODcuMTI5LDM1NC42Mjl2NjcuMjdjMCw3LjcwNC02LjQ0OSwxNC4yMjItMTQuMTU5LDE0LjIyMmgtMzEuODM0ICBjLTcuNzEsMC0xNC4xNTktNi41MTgtMTQuMTU5LTE0LjIyMnYtNjcuMjdjLTcuNDc3LTcuMzYxLTExLjgzLTE3LjUzNy0xMS44My0yOC43OTVjMC0yMS4zMzQsMTYuNDkxLTM5LjY2NiwzNy40NTktNDAuNTEyICBjMi4yMjItMC4wOSw2LjY3My0wLjA5LDguODk1LDBjMjAuOTY4LDAuODQ2LDM3LjQ1OSwxOS4xNzgsMzcuNDU5LDQwLjUxMkMyOTguOTU5LDMzNy4wOTIsMjk0LjYwNSwzNDcuMjY4LDI4Ny4xMjksMzU0LjYyOXogTTM0NS41NzIsMjA5LjgzSDI2MS41aC04Ljg5NWgtODQuMDcydi00NC4zODhjMC00OC45MDUsMzkuNzQ0LTg5LjM0Miw4OC41MTktODkuMzQyczg4LjUyLDQwLjQzNyw4OC41Miw4OS4zNDJWMjA5LjgzeiIvPjwvc3ZnPg=='); margin: 5px; top: 1px; position:relative; } #wpmchimpa-main .wpmchimpa-social{ display: inline-block; margin: 12px auto 0; height: 90px; width: 100%; background: rgba(75, 75, 75, 0.3); box-shadow: 0px 1px 1px 1px rgba(116, 116, 116, 0.94); } #wpmchimpa-main .wpmchimpa-social::before{ content: 'Subscribe with'; font-size: 13px; color: #ADACB2; width: 100%; display: block; margin: 15px auto 5px; } #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc{ display: inline-block; width:40px; height: 40px; border-radius: 2px; cursor: pointer; -webkit-transition: all 0.1s ease; transition: all 0.1s ease; -webkit-backface-visibility:hidden; border:1px solid #262E43; border-color: #ffffff;} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc::before{ content: ''; display: block; width:40px; height: 40px; background: no-repeat center; } #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-fb { display:none;} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-fb::before { background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI5Ni4yOTYsNTEySDIwMC4zNlYyNTZoLTY0di04OC4yMjVsNjQtMC4wMjlsLTAuMTA0LTUxLjk3NkMyMDAuMjU2LDQzLjc5NCwyMTkuNzczLDAsMzA0LjU1NiwwaDcwLjU4OHY4OC4yNDJoLTQ0LjExNSBjLTMzLjAxNiwwLTM0LjYwNCwxMi4zMjgtMzQuNjA0LDM1LjM0MmwtMC4xMzEsNDQuMTYyaDc5LjM0NmwtOS4zNTQsODguMjI1TDI5Ni4zNiwyNTZMMjk2LjI5Niw1MTJ6Ii8+PC9zdmc+')} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-fb:hover:before { background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMyZDYwOWIiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI5Ni4yOTYsNTEySDIwMC4zNlYyNTZoLTY0di04OC4yMjVsNjQtMC4wMjlsLTAuMTA0LTUxLjk3NkMyMDAuMjU2LDQzLjc5NCwyMTkuNzczLDAsMzA0LjU1NiwwaDcwLjU4OHY4OC4yNDJoLTQ0LjExNSBjLTMzLjAxNiwwLTM0LjYwNCwxMi4zMjgtMzQuNjA0LDM1LjM0MmwtMC4xMzEsNDQuMTYyaDc5LjM0NmwtOS4zNTQsODguMjI1TDI5Ni4zNiwyNTZMMjk2LjI5Niw1MTJ6Ii8+PC9zdmc+')} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-gp { display:none;} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-gp:before { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI3My4zNzIsMzAyLjQ5OGMtNS4wNDEtNi43NjItMTAuNjA4LTEzLjA0NS0xNi43LTE4Ljg0MmMtNi4wOTEtNS44MDQtMTIuMTgzLTExLjA4OC0xOC4yNzEtMTUuODQ1IGMtNi4wOTItNC43NTctMTEuNjU5LTkuMzI5LTE2LjcwMi0xMy43MDljLTUuMDQyLTQuMzc0LTkuMTM1LTguOTQ1LTEyLjI3NS0xMy43MDJjLTMuMTQtNC43NTctNC43MTEtOS42MS00LjcxMS0xNC41NTggYzAtNi44NTUsMi4xOS0xMy4yNzgsNi41NjctMTkuMjc0YzQuMzc3LTUuOTk2LDkuNzA3LTExLjc5OSwxNS45ODYtMTcuNDE3YzYuMjgtNS42MTcsMTIuNTU5LTExLjc1MywxOC44NDQtMTguNDE1IGM2LjI3Ni02LjY2NSwxMS42MDQtMTUuNDY1LDE1Ljk4NS0yNi40MTJjNC4zNzMtMTAuOTQ0LDYuNTYzLTIzLjQ1OCw2LjU2My0zNy41NDJjMC0xNi43NS0zLjcxMy0zMi44MzUtMTEuMTM2LTQ4LjI1IGMtNy40MjMtMTUuNDE4LTE3Ljg5LTI3LjQxMi0zMS40MDUtMzUuOTc2aDM4LjU0TDMwMy4yLDBIMTc4LjQ0MWMtMTcuNjk5LDAtMzUuNDk4LDEuOTA2LTUzLjM4NCw1LjcyIGMtMjYuNDUzLDUuOS00OC43MjMsMTkuMzY4LTY2LjgwNiw0MC4zOTdDNDAuMTcxLDY3LjE1LDMxLjEyOSw5MC45OSwzMS4xMjksMTE3LjYzN2MwLDI4LjE3MSwxMC4xMzgsNTEuNTgzLDMwLjQwNiw3MC4yMzMgYzIwLjI2OSwxOC42NDksNDQuNTg1LDI3Ljk3OCw3Mi45NDUsMjcuOTc4YzUuNzEsMCwxMi4zNzEtMC40NzgsMTkuOTg1LTEuNDI3Yy0wLjM4MSwxLjUyMS0xLjA0MywzLjU2Ny0xLjk5Nyw2LjEzNiBzLTEuNzE1LDQuNjItMi4yODYsNi4xNGMtMC41NywxLjUyMS0xLjA0NywzLjM3NS0xLjQyNSw1LjU2NmMtMC4zODIsMi4xOS0wLjU3MSw0LjQyOC0wLjU3MSw2LjcxIGMwLDEyLjU2Myw2LjA4NiwyNi43NDQsMTguMjcxLDQyLjU0MWMtMTQuNDY1LDAuMzg3LTI4LjczNywxLjY3LTQyLjgyNSwzLjg2Yy0xNC4wODQsMi4xOS0yOC44MzMsNS42MTYtNDQuMjUyLDEwLjI4IGMtMTUuNDE3LDQuNjYxLTI5LjIxNywxMS40Mi00MS4zOTYsMjAuMjdjLTEyLjE4Miw4Ljg1NC0yMS4zMTcsMTkuMzY2LTI3LjQwOCwzMS41NDlDMy41MzMsMzYxLjU1OSwwLjAxLDM3NC40MDUsMC4wMSwzODYuMDE3IGMwLDEyLjc1MSwyLjg1NywyNC4zMTQsOC41NjUsMzQuNjljNS43MDgsMTAuMzY5LDEzLjAzNSwxOC44NDIsMjEuOTgyLDI1LjQwNmM4Ljk0NSw2LjU3LDE5LjI3MywxMi4wODMsMzAuOTc4LDE2LjU2MiBjMTEuNzA0LDQuNDcsMjMuMzE1LDcuNjU5LDM0LjgyOSw5LjU2MmMxMS41MTYsMS45MDMsMjIuODg4LDIuODU0LDM0LjExOSwyLjg1NGM1MS4wMDcsMCw5MC45ODEtMTIuNDY0LDExOS45MDktMzcuMzk3IGMyNi42NDgtMjMuMjIzLDM5Ljk3MS01MC4wNjIsMzkuOTcxLTgwLjUxN2MwLTEwLjg1NS0xLjU3LTIwLjk4NC00LjcxMi0zMC40MDlDMjgyLjUxLDMxNy4zMzcsMjc4LjQyLDMwOS4yNTQsMjczLjM3MiwzMDIuNDk4eiBNMTYzLjMxMSwxOTguNzIyYy05LjcwNywwLTE4LjkzNy0yLjQ3NS0yNy42OTQtNy40MjZjLTguNzU3LTQuOTUtMTYuMTgtMTEuMzc0LTIyLjI3LTE5LjI3MyBjLTYuMDg4LTcuODk4LTExLjQxOC0xNi43OTYtMTUuOTg3LTI2LjY5NWMtNC41NjctOS44OTYtNy45NDQtMTkuNzkyLTEwLjEzNS0yOS42OTJjLTIuMTktOS44OTUtMy4yODQtMTkuMzE4LTMuMjg0LTI4LjI2NSBjMC0xOC4yNzEsNC44NTQtMzMuOTc0LDE0LjU2Mi00Ny4xMDhjOS43MDUtMTMuMTM0LDIzLjQxMS0xOS43MDEsNDEuMTEyLTE5LjcwMWMxMi41NjMsMCwyMy45MzUsMy44OTksMzQuMTE4LDExLjcwNCBjMTAuMTgzLDcuODA0LDE4LjE3NywxNy43MDEsMjMuOTg0LDI5LjY5MmM1LjgwMiwxMS45OTEsMTAuMjc3LDI0LjQwNywxMy40MTcsMzcuMjU3YzMuMTQsMTIuODQ3LDQuNzExLDI0Ljk4Myw0LjcxMSwzNi40MDMgYzAsMTkuMDM2LTQuMTM5LDM0LjMxNy0xMi40MTksNDUuODMzQzE5NS4xNDQsMTkyLjk2NCwxODEuNzc1LDE5OC43MjIsMTYzLjMxMSwxOTguNzIyeiBNMjQyLjI1MSw0MTMuMTIzIGMtNS4yMyw4Ljk0OS0xMi4zMTksMTUuOTQtMjEuMjY3LDIwLjk4MWMtOC45NDYsNS4wNDgtMTguNTA5LDguNzU4LTI4LjY5MywxMS4xNGMtMTAuMTgzLDIuMzg1LTIwLjg4OSwzLjU3Mi0zMi4xMiwzLjU3MiBjLTEyLjE4MiwwLTI0LjI3LTEuNDMxLTM2LjI1OC00LjI4NGMtMTEuOTktMi44NTEtMjMuNDU5LTcuMTg3LTM0LjQwMy0xMi45OTFjLTEwLjk0NC01LjgtMTkuNzk1LTEzLjc5OC0yNi41NTEtMjMuOTgyIGMtNi43NTctMTAuMTg0LTEwLjEzNS0yMS43NDQtMTAuMTM1LTM0LjY5YzAtMTEuNDE5LDIuNTY4LTIxLjYwMSw3LjcwOC0zMC41NWM1LjE0Mi04Ljk0NSwxMS43MDktMTYuMDg0LDE5LjcwMi0yMS40MDggYzcuOTk0LTUuMzMyLDE3LjMxOS05LjcxMywyNy45NzktMTMuMTMxYzEwLjY2LTMuNDMzLDIwLjkzNy01LjgwOCwzMC44MzMtNy4xMzljOS44OTUtMS4zMzUsMTkuOTg1LTEuOTk1LDMwLjI2Mi0xLjk5NSBjNi4yODMsMCwxMS4wNDMsMC4xOTEsMTQuMjc3LDAuNTY3YzEuMTQzLDAuNzY3LDQuMDQzLDIuNzU5LDguNzA4LDUuOTk2czcuODA0LDUuNDI4LDkuNDIzLDYuNTcgYzEuNjE1LDEuMTM3LDQuNTY3LDMuMzI2LDguODUsNi41NjNjNC4yODEsMy4yMzcsNy4zMjcsNS42NjEsOS4xMzUsNy4yNzljMS44MDMsMS42MTgsNC40MjEsNC4wNDUsNy44NDksNy4yNzkgYzMuNDI0LDMuMjM3LDUuOTQ4LDYuMDQzLDcuNTY2LDguNDIyYzEuNjE1LDIuMzc4LDMuNjE2LDUuMjgsNS45OTYsOC43MDJjMi4zOCwzLjQzMyw0LjA0Myw2LjcxNSw0Ljk5OCw5Ljg1NSBjMC45NDgsMy4xNDIsMS44NTQsNi41NjcsMi43MDcsMTAuMjc3YzAuODU1LDMuNzIsMS4yODMsNy41NjksMS4yODMsMTEuNTdDMjUwLjEwNSwzOTMuNzEzLDI0Ny40ODcsNDA0LjE4MiwyNDIuMjUxLDQxMy4xMjN6Ii8+IDxwb2x5Z29uIHBvaW50cz0iNDAxLjk5OCw3My4wODkgNDAxLjk5OCwwIDM2NS40NDksMCAzNjUuNDQ5LDczLjA4OSAyOTIuMzU4LDczLjA4OSAyOTIuMzU4LDEwOS42MzYgMzY1LjQ0OSwxMDkuNjM2ICAzNjUuNDQ5LDE4Mi43MjUgNDAxLjk5OCwxODIuNzI1IDQwMS45OTgsMTA5LjYzNiA0NzUuMDgxLDEwOS42MzYgNDc1LjA4MSw3My4wODkiLz48L3N2Zz4=')} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-gp:hover:before { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNlYjQwMjYiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBhdGggZD0iTTI3My4zNzIsMzAyLjQ5OGMtNS4wNDEtNi43NjItMTAuNjA4LTEzLjA0NS0xNi43LTE4Ljg0MmMtNi4wOTEtNS44MDQtMTIuMTgzLTExLjA4OC0xOC4yNzEtMTUuODQ1IGMtNi4wOTItNC43NTctMTEuNjU5LTkuMzI5LTE2LjcwMi0xMy43MDljLTUuMDQyLTQuMzc0LTkuMTM1LTguOTQ1LTEyLjI3NS0xMy43MDJjLTMuMTQtNC43NTctNC43MTEtOS42MS00LjcxMS0xNC41NTggYzAtNi44NTUsMi4xOS0xMy4yNzgsNi41NjctMTkuMjc0YzQuMzc3LTUuOTk2LDkuNzA3LTExLjc5OSwxNS45ODYtMTcuNDE3YzYuMjgtNS42MTcsMTIuNTU5LTExLjc1MywxOC44NDQtMTguNDE1IGM2LjI3Ni02LjY2NSwxMS42MDQtMTUuNDY1LDE1Ljk4NS0yNi40MTJjNC4zNzMtMTAuOTQ0LDYuNTYzLTIzLjQ1OCw2LjU2My0zNy41NDJjMC0xNi43NS0zLjcxMy0zMi44MzUtMTEuMTM2LTQ4LjI1IGMtNy40MjMtMTUuNDE4LTE3Ljg5LTI3LjQxMi0zMS40MDUtMzUuOTc2aDM4LjU0TDMwMy4yLDBIMTc4LjQ0MWMtMTcuNjk5LDAtMzUuNDk4LDEuOTA2LTUzLjM4NCw1LjcyIGMtMjYuNDUzLDUuOS00OC43MjMsMTkuMzY4LTY2LjgwNiw0MC4zOTdDNDAuMTcxLDY3LjE1LDMxLjEyOSw5MC45OSwzMS4xMjksMTE3LjYzN2MwLDI4LjE3MSwxMC4xMzgsNTEuNTgzLDMwLjQwNiw3MC4yMzMgYzIwLjI2OSwxOC42NDksNDQuNTg1LDI3Ljk3OCw3Mi45NDUsMjcuOTc4YzUuNzEsMCwxMi4zNzEtMC40NzgsMTkuOTg1LTEuNDI3Yy0wLjM4MSwxLjUyMS0xLjA0MywzLjU2Ny0xLjk5Nyw2LjEzNiBzLTEuNzE1LDQuNjItMi4yODYsNi4xNGMtMC41NywxLjUyMS0xLjA0NywzLjM3NS0xLjQyNSw1LjU2NmMtMC4zODIsMi4xOS0wLjU3MSw0LjQyOC0wLjU3MSw2LjcxIGMwLDEyLjU2Myw2LjA4NiwyNi43NDQsMTguMjcxLDQyLjU0MWMtMTQuNDY1LDAuMzg3LTI4LjczNywxLjY3LTQyLjgyNSwzLjg2Yy0xNC4wODQsMi4xOS0yOC44MzMsNS42MTYtNDQuMjUyLDEwLjI4IGMtMTUuNDE3LDQuNjYxLTI5LjIxNywxMS40Mi00MS4zOTYsMjAuMjdjLTEyLjE4Miw4Ljg1NC0yMS4zMTcsMTkuMzY2LTI3LjQwOCwzMS41NDlDMy41MzMsMzYxLjU1OSwwLjAxLDM3NC40MDUsMC4wMSwzODYuMDE3IGMwLDEyLjc1MSwyLjg1NywyNC4zMTQsOC41NjUsMzQuNjljNS43MDgsMTAuMzY5LDEzLjAzNSwxOC44NDIsMjEuOTgyLDI1LjQwNmM4Ljk0NSw2LjU3LDE5LjI3MywxMi4wODMsMzAuOTc4LDE2LjU2MiBjMTEuNzA0LDQuNDcsMjMuMzE1LDcuNjU5LDM0LjgyOSw5LjU2MmMxMS41MTYsMS45MDMsMjIuODg4LDIuODU0LDM0LjExOSwyLjg1NGM1MS4wMDcsMCw5MC45ODEtMTIuNDY0LDExOS45MDktMzcuMzk3IGMyNi42NDgtMjMuMjIzLDM5Ljk3MS01MC4wNjIsMzkuOTcxLTgwLjUxN2MwLTEwLjg1NS0xLjU3LTIwLjk4NC00LjcxMi0zMC40MDlDMjgyLjUxLDMxNy4zMzcsMjc4LjQyLDMwOS4yNTQsMjczLjM3MiwzMDIuNDk4eiBNMTYzLjMxMSwxOTguNzIyYy05LjcwNywwLTE4LjkzNy0yLjQ3NS0yNy42OTQtNy40MjZjLTguNzU3LTQuOTUtMTYuMTgtMTEuMzc0LTIyLjI3LTE5LjI3MyBjLTYuMDg4LTcuODk4LTExLjQxOC0xNi43OTYtMTUuOTg3LTI2LjY5NWMtNC41NjctOS44OTYtNy45NDQtMTkuNzkyLTEwLjEzNS0yOS42OTJjLTIuMTktOS44OTUtMy4yODQtMTkuMzE4LTMuMjg0LTI4LjI2NSBjMC0xOC4yNzEsNC44NTQtMzMuOTc0LDE0LjU2Mi00Ny4xMDhjOS43MDUtMTMuMTM0LDIzLjQxMS0xOS43MDEsNDEuMTEyLTE5LjcwMWMxMi41NjMsMCwyMy45MzUsMy44OTksMzQuMTE4LDExLjcwNCBjMTAuMTgzLDcuODA0LDE4LjE3NywxNy43MDEsMjMuOTg0LDI5LjY5MmM1LjgwMiwxMS45OTEsMTAuMjc3LDI0LjQwNywxMy40MTcsMzcuMjU3YzMuMTQsMTIuODQ3LDQuNzExLDI0Ljk4Myw0LjcxMSwzNi40MDMgYzAsMTkuMDM2LTQuMTM5LDM0LjMxNy0xMi40MTksNDUuODMzQzE5NS4xNDQsMTkyLjk2NCwxODEuNzc1LDE5OC43MjIsMTYzLjMxMSwxOTguNzIyeiBNMjQyLjI1MSw0MTMuMTIzIGMtNS4yMyw4Ljk0OS0xMi4zMTksMTUuOTQtMjEuMjY3LDIwLjk4MWMtOC45NDYsNS4wNDgtMTguNTA5LDguNzU4LTI4LjY5MywxMS4xNGMtMTAuMTgzLDIuMzg1LTIwLjg4OSwzLjU3Mi0zMi4xMiwzLjU3MiBjLTEyLjE4MiwwLTI0LjI3LTEuNDMxLTM2LjI1OC00LjI4NGMtMTEuOTktMi44NTEtMjMuNDU5LTcuMTg3LTM0LjQwMy0xMi45OTFjLTEwLjk0NC01LjgtMTkuNzk1LTEzLjc5OC0yNi41NTEtMjMuOTgyIGMtNi43NTctMTAuMTg0LTEwLjEzNS0yMS43NDQtMTAuMTM1LTM0LjY5YzAtMTEuNDE5LDIuNTY4LTIxLjYwMSw3LjcwOC0zMC41NWM1LjE0Mi04Ljk0NSwxMS43MDktMTYuMDg0LDE5LjcwMi0yMS40MDggYzcuOTk0LTUuMzMyLDE3LjMxOS05LjcxMywyNy45NzktMTMuMTMxYzEwLjY2LTMuNDMzLDIwLjkzNy01LjgwOCwzMC44MzMtNy4xMzljOS44OTUtMS4zMzUsMTkuOTg1LTEuOTk1LDMwLjI2Mi0xLjk5NSBjNi4yODMsMCwxMS4wNDMsMC4xOTEsMTQuMjc3LDAuNTY3YzEuMTQzLDAuNzY3LDQuMDQzLDIuNzU5LDguNzA4LDUuOTk2czcuODA0LDUuNDI4LDkuNDIzLDYuNTcgYzEuNjE1LDEuMTM3LDQuNTY3LDMuMzI2LDguODUsNi41NjNjNC4yODEsMy4yMzcsNy4zMjcsNS42NjEsOS4xMzUsNy4yNzljMS44MDMsMS42MTgsNC40MjEsNC4wNDUsNy44NDksNy4yNzkgYzMuNDI0LDMuMjM3LDUuOTQ4LDYuMDQzLDcuNTY2LDguNDIyYzEuNjE1LDIuMzc4LDMuNjE2LDUuMjgsNS45OTYsOC43MDJjMi4zOCwzLjQzMyw0LjA0Myw2LjcxNSw0Ljk5OCw5Ljg1NSBjMC45NDgsMy4xNDIsMS44NTQsNi41NjcsMi43MDcsMTAuMjc3YzAuODU1LDMuNzIsMS4yODMsNy41NjksMS4yODMsMTEuNTdDMjUwLjEwNSwzOTMuNzEzLDI0Ny40ODcsNDA0LjE4MiwyNDIuMjUxLDQxMy4xMjN6Ii8+IDxwb2x5Z29uIHBvaW50cz0iNDAxLjk5OCw3My4wODkgNDAxLjk5OCwwIDM2NS40NDksMCAzNjUuNDQ5LDczLjA4OSAyOTIuMzU4LDczLjA4OSAyOTIuMzU4LDEwOS42MzYgMzY1LjQ0OSwxMDkuNjM2ICAzNjUuNDQ5LDE4Mi43MjUgNDAxLjk5OCwxODIuNzI1IDQwMS45OTgsMTA5LjYzNiA0NzUuMDgxLDEwOS42MzYgNDc1LjA4MSw3My4wODkiLz48L3N2Zz4=')} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-ms { display:none;} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-ms::before { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTcgMTciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDE3IDE3IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBkPSJNOC4wMjEsMS4zODV2Ni40MzdoOC43OTFWMC4xMjdMOC4wMjEsMS4zODV6IE0wLDcuODIyaDYuNjQ4VjEuNDk0TDAsMi40NDNWNy44MjJ6IE0wLDE0LjE3NSBsNi42NDgsMS4wMzFWOC42M0gwVjE0LjE3NXogTTguMDIxLDE1LjMyMWw4Ljc5MSwxLjM2NFY4LjYzSDguMDIxVjE1LjMyMXoiLz48L3N2Zz4=')} #wpmchimpa-main .wpmchimpa-social .wpmchimpa-soc.wpmchimpa-ms:hover:before { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiMwMEJDRjIiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgMTcgMTciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDE3IDE3IiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBkPSJNOC4wMjEsMS4zODV2Ni40MzdoOC43OTFWMC4xMjdMOC4wMjEsMS4zODV6IE0wLDcuODIyaDYuNjQ4VjEuNDk0TDAsMi40NDNWNy44MjJ6IE0wLDE0LjE3NSBsNi42NDgsMS4wMzFWOC42M0gwVjE0LjE3NXogTTguMDIxLDE1LjMyMWw4Ljc5MSwxLjM2NFY4LjYzSDguMDIxVjE1LjMyMXoiLz48L3N2Zz4=')} #wpmchimpa-main .wpmchimpa-close-button{ position: absolute; display: block; top: 0; right: 0; width: 25px; text-align: center; cursor: pointer; } #wpmchimpa-main .wpmchimpa-close-button::before{ content: "\00D7"; font-size: 25px; line-height: 25px; font-weight: 100; color: #999; opacity: 0.4; color:;} #wpmchimpa-main .wpmchimpa-close-button:hover:before{ opacity: 1; } #wpmchimpa-main .wpmchimpa-feedback.wpmchimpa-done{ font-size: 15px; margin: 10px; height: auto;} #wpmchimpa-main .wpmchimpa-feedback.wpmchimpa-done:before{ content:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMTVweCIgaGVpZ2h0PSIxNXB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSIxNDIuOCwzMjMuODUgMzUuNywyMTYuNzUgMCwyNTIuNDUgMTQyLjgsMzk1LjI1IDQ0OC44LDg5LjI1IDQxMy4xLDUzLjU1Ii8+PC9zdmc+'); width: 40px; height: 40px; border-radius: 20px; line-height: 46px; display: block; background-color: #01E169; margin: 40px auto; } .wpmc_2col #wpmchimpa .wpmc_colsplit{ width: calc(50% - 5px); display: inline-block; float: left; } .wpmc_2col #wpmchimpa .wpmc_coleven{ margin-left: 10px; } @media only screen and (max-width: 600px){ .wpmc_2col #wpmchimpa .wpmc_colsplit{ width: 100%; margin-left: 0; } } .animated { -webkit-animation-duration: 1s; animation-duration: 1s; -webkit-animation-fill-mode: both; animation-fill-mode: both; } @-webkit-keyframes bounceInDown { 0%, 60%, 75%, 90%, 100% { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: translate3d(0, -3000px, 0); transform: translate3d(0, -3000px, 0); } 60% { opacity: 1; -webkit-transform: translate3d(0, 25px, 0); transform: translate3d(0, 25px, 0); } 75% { -webkit-transform: translate3d(0, -10px, 0); transform: translate3d(0, -10px, 0); } 90% { -webkit-transform: translate3d(0, 5px, 0); transform: translate3d(0, 5px, 0); } 100% { -webkit-transform: none; transform: none; } } @keyframes bounceInDown { 0%, 60%, 75%, 90%, 100% { -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); } 0% { opacity: 0; -webkit-transform: translate3d(0, -3000px, 0); transform: translate3d(0, -3000px, 0); } 60% { opacity: 1; -webkit-transform: translate3d(0, 25px, 0); transform: translate3d(0, 25px, 0); } 75% { -webkit-transform: translate3d(0, -10px, 0); transform: translate3d(0, -10px, 0); } 90% { -webkit-transform: translate3d(0, 5px, 0); transform: translate3d(0, 5px, 0); } 100% { -webkit-transform: none; transform: none; } } .bounceInDown { -webkit-animation-name: bounceInDown; animation-name: bounceInDown; } .animatedout { -webkit-animation-duration: 1s; animation-duration: 1s; -webkit-animation-fill-mode: both; animation-fill-mode: both; } @-webkit-keyframes rollOut { 0% { opacity: 1; } 100% { opacity: 0; -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); } } @keyframes rollOut { 0% { opacity: 1; } 100% { opacity: 0; -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); } } .rollOut { -webkit-animation-name: rollOut; animation-name: rollOut; } @-webkit-keyframes zoomIn { 0% { opacity: 0; -webkit-transform: scale3d(.3, .3, .3); transform: scale3d(.3, .3, .3); } 50% { opacity: 1; } } </style> <div class="wpmchimpa-reset wpmchimpa-overlay-bg wpmchimpselector chimpmatecss"> <div class="wpmchimpa-maina bounceInDown animated" wpmcexitanim> <div class="wpmchimpa-mainc"> <div id="wpmchimpa-main"> <div id="wpmchimpa-newsletterform" class="wpmchimpa-wrapper"> <div class="wpmchimpa" id="wpmchimpa"> <h3>DZWON</h3> <div class="wpmchimpa_para"><div style="text-align: center;">Są tacy, którzy czytają tę wiadomość przed tobą.</div><div style="text-align: center;">Zapisz się, aby otrzymywać najnowsze artykuły. <img src="http://" loading=lazy></div></div> <form wpmc_suc wpmc_msg="Спасибо! ПРОВЕРЬТЕ ПОЧТУ" action="" method="post"> <input type="hidden" name="action" value="wpmchimpa_add_email_ajax"/> <input type="hidden" name="wpmcform" value="1"/> <div class="formbox wpmchimpa-field"><div class="wpmchimpa-text wpmc-ficon"><input type="text" name="email" wpmctype="email" wpmcfield="email" wpmcreq="true" required/><span class="inputlabel">E-mail</span><span class="inputicon"></span><div class="wpmcinfierr" wpmcerr="email"></div></div><div class="wpmchimpa-subsc"><div class="wpmchimpa-subs-button"></div><div class="wpmchimpa-signal"><style type="text/css">#wpmchimpa-main .sp8 { margin: 0 auto;width: 50px;height: 30px;} #wpmchimpa-main .sp8 > div { background-color: #3d3d3d;margin-left: 3px;height: 100%;width: 6px;display: inline-block;-webkit-animation: wpmchimpa-mainsp8 1.2s infinite ease-in-out;animation: wpmchimpa-mainsp8 1.2s infinite ease-in-out;} #wpmchimpa-main .sp8 .sp82 { -webkit-animation-delay: -1.1s;animation-delay: -1.1s;} #wpmchimpa-main .sp8 .sp83 { -webkit-animation-delay: -1.0s;animation-delay: -1.0s;} #wpmchimpa-main .sp8 .sp84 { -webkit-animation-delay: -0.9s;animation-delay: -0.9s;} #wpmchimpa-main .sp8 .sp85 { -webkit-animation-delay: -0.8s;animation-delay: -0.8s;} @-webkit-keyframes wpmchimpa-mainsp8 { 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 20% { -webkit-transform: scaleY(1.0) } }@keyframes wpmchimpa-mainsp8 { 0%, 40%, 100% { transform: scaleY(0.4);-webkit-transform: scaleY(0.4);} 20% { transform: scaleY(1.0);-webkit-transform: scaleY(1.0);} }</style><div class="sp8"><div class="sp81"></div><div class="sp82"></div><div class="sp83"></div><div class="sp84"></div><div class="sp85"></div></div></div></div><div style="clear:both"></div></div><div class="wpmchimpa-field wpmchimpa-text wpmc_colsplit wpmc-ficon"><input type="text" name="merge_fields[FNAME]" wpmctype="text" wpmcfield="FNAME" wpmcreq="true" required/><span class="inputlabel">Imię</span><span class="inputicon"></span><div class="wpmcinfierr" wpmcerr="FNAME"></div></div><div class="wpmchimpa-field wpmchimpa-text wpmc_colsplit wpmc-ficon"><input type="text" name="merge_fields[LNAME]" wpmctype="text" wpmcfield="LNAME" wpmcreq="true" required/><span class="inputlabel">Nazwisko</span><span class="inputicon"></span><div class="wpmcinfierr" wpmcerr="LNAME"></div></div><div class="wpmchimpa-field wpmchimpa-radio"><div class="wpmchimpa-itemh">Jak chcesz przeczytać The Bell</div><div class="wpmchimpa-itemb"><label class="wpmchimpa-item"><input type="radio" name="group[f899931c09]" value="a22e2103b4" wpmctype="radio" wpmcfield="f899931c09" wpmcreq="true"><span>Dwa razy dziennie</span></label><label class="wpmchimpa-item"><input type="radio" name="group[f899931c09]" value="4ab55de31a" wpmctype="radio" wpmcfield="f899931c09" wpmcreq="true"><span>Mailing rano</span></label><label class="wpmchimpa-item"><input type="radio" name="group[f899931c09]" value="e386c1935e" wpmctype="radio" wpmcfield="f899931c09" wpmcreq="true"><span>Mailing wieczorny</span></label></div><div class="wpmcinfierr" wpmcerr="f899931c09"></div></div> <div style="clear:both"></div> <div class="wpmchimpa-tag">Bez spamu</div> </form> <div class="wpmchimpa-feedback" wpmcerr="gen"></div> </div> </div> <div class="wpmchimpa-close-button"></div> </div> </div> </div> </div><script data-cfasync="false" src="/cdn-cgi/scripts/af2821b0/cloudflare-static/email-decode.min.js"></script><script type='text/javascript' src='https://qipu.ru/wp-content/themes/authentic/js/vendors.min.js?ver=201710093'></script> <script type='text/javascript'> /* <![CDATA[ */ var translation = { "next":"Next","previous":"Previous"} ; /* ]]> */ </script> <script type='text/javascript' src='https://qipu.ru/wp-content/themes/authentic/js/scripts.js?ver=201710093'></script> <script type='text/javascript' src='/wp-includes/js/wp-embed.min.js?ver=9.9.9'></script> <script type='text/javascript' src='https://qipu.ru/wp-content/plugins/chimpmatepro/public/assets/js/public.js?ver=1.3.2'></script> </body> </html>