XML ( Engleză eXtensible Markup Language ) limbaj de marcare extensibil | |
---|---|
Extensie | .xml |
tip MIME | application/xml [1] , text/xml [2] (depreciat într-o schiță expirată) [3] |
Dezvoltator | Consorțiul World Wide Web |
publicat | 1998 |
Tip de format | limbaj de marcare |
Extins din | SGML |
Dezvoltat în | XHTML , RSS , Atom , KML , SVG și multe alte formate |
Standard(e) |
1.0 (Ediția a cincea), 26 noiembrie 2008 [4] 1.1 (Ediția a doua), 16 august 2006 [5] |
format deschis ? | da |
Site-ul web | w3.org/XML _ |
Fișiere media la Wikimedia Commons |
XML ( MFA : [ ˌ e k s . e m ˈ e l ], prescurtare din engleză. e X tensible Markup Language ) - „ limbaj de markup extensibil ”. Recomandat de World Wide Web Consortium (W3C). Specificația XML descrie documentele XML și descrie parțial comportamentul procesoarelor XML (programe care citesc documente XML și oferă acces la conținutul acestora). XML a fost conceput pentru a fi un limbaj cu o sintaxă formală simplă , ușor de creat și procesat documente atât pentru programe , cât și pentru oameni , cu accent pe utilizarea pe Internet. Limbajul se numește extensibil deoarece nu fixează markupul folosit în documente: dezvoltatorul este liber să creeze markup în funcție de nevoile unei anumite zone, fiind limitat doar de regulile de sintaxă ale limbajului. O extensie XML este o gramatică concretă bazată pe XML și reprezentată de un dicționar de etichete și atributele acestora, precum și un set de reguli care definesc ce atribute și elemente pot fi conținute în alte elemente. Combinația dintre sintaxa formală simplă, ușurința umană, extensibilitatea și încrederea în codificări Unicode pentru reprezentarea conținutului documentelor a condus la utilizarea pe scară largă atât a XML-ului însuși, cât și a unei varietăți de limbaje specializate derivate din XML într-o mare varietate de instrumente software.
XML este un subset al SGML .
Specificația XML descrie limbajul și o serie de probleme privind codificarea și procesarea documentelor. Materialul din această secțiune este un rezumat al descrierii limbii din specificația XML, adaptată pentru acest articol.
Versiunea în limba engleză a documentului este considerată normativă, prin urmare termenii principali sunt dați împreună cu originalele lor în limba engleză.
Traducerea termenilor principali urmează, practic, traducerea Specificației în rusă disponibilă pe Internet, cu excepția termenilor etichetă și declarație . Pentru termenul etichetă, eticheta de traducere este folosită aici . Pentru termenul declarație, se acordă preferință declarației comune de traducere ( față de declarația comună, de asemenea, pe hârtie de calc ).
Alte traduceri ale termenilor principali pot fi găsite în literatură și pe Internet.
Din punct de vedere fizic, un document este format din entități , fiecare dintre acestea putând face referire la o altă entitate. Unicul element rădăcină este entitatea document . Conținutul entităților este simboluri.
Din punct de vedere logic, documentul este format din comentarii ( English comments ), declarații ( English declarations ), elemente ( English elements ), referințe de entități ( English character references ) și instrucțiuni de procesare ( English processing instructions ). Toate acestea din document sunt structurate prin marcare .
Structura fizicăO entitate este cea mai mică parte dintr-un document. Toate entitățile conțin ceva și toate au un nume (există excepții, de exemplu document entity ). Mai simplu spus, termenul „esență” descrie „lucru existent”, „ ceva ” [6] .
Un document este format din entități al căror conținut este simboluri. Toate caracterele sunt împărțite în două tipuri: caractere de date (date de caractere în limba engleză ) și caractere de marcare. Markup include:
Partea non-markup a documentului este datele de caracter ale documentului.
Structura logicăToate părțile constitutive ale documentului sunt rezumate în prolog și elementul rădăcină . Elementul rădăcină este o parte obligatorie a documentului, care constituie întreaga sa esență (prologul, în general, poate fi absent). Elementul rădăcină poate include sau nu elementele sale imbricate, datele de caracter și comentariile. Elementele imbricate în elementul rădăcină pot include, la rândul lor, elemente imbricate, date de caracter și comentarii și așa mai departe. Prolog poate include declarații , instrucțiuni de procesare , comentarii . Ar trebui să înceapă cu o declarație XML , deși această declarație poate fi omisă în anumite situații.
Elementele de document trebuie să fie imbricate corespunzător : orice element care începe în interiorul altui element (adică orice element de document, altul decât elementul rădăcină) trebuie să se termine în interiorul elementului pe care a început. Datele de caractere pot apărea în cadrul elementelor fie direct, fie în secțiuni speciale „CDATA” . Declarațiile, instrucțiunile de procesare și elementele pot avea atribute asociate acestora. Atributele sunt folosite pentru a asocia perechile nume-valoare cu o unitate logică de text.
Markupul începe întotdeauna cu un caracter <și se termină cu un >.
Alături de simbolurile <și >, simbolul joacă și un rol special în marcare &. Parantezele unghiulare marchează granițele elementelor, instrucțiunilor de procesare și alte secvențe. Ampersand vă permite să înlocuiți text folosind entități ( entități engleze ) [6] .
Utilizarea caracterelor de marcare în datele de caractere face dificilă recunoașterea constructelor de marcare și poate crea o problemă de ambiguitate a structurii. În XML, această problemă este rezolvată după cum urmează: <, > și & nu pot fi prezente în datele de caracter și în valorile atributelor în forma lor directă, entitățile speciale sunt rezervate pentru reprezentarea lor în aceste cazuri :
Simbol | Înlocuire |
---|---|
< | < |
> | > |
& | & |
În plus, următoarele entități sunt folosite pentru a folosi apostrofe și ghilimele în cadrul valorilor atributelor :
' | ' |
" | " |
Regula de înlocuire a caracterelor de marcare cu entitățile lor care denotă nu se aplică datelor de caractere din secțiunile „CDATA”, ci se realizează în toate celelalte locuri din document.
Referințele de caractere numerice indică poziția codului caracterului în setul de caractere al documentului. Referințele de caractere numerice pot lua două forme [7] :
Exemple de referințe de caractere numerice:
În XML, toate numele trebuie să înceapă cu o literă, caracterul de subliniere (_) și să continue doar cu caracterele care sunt permise pentru nume, și anume: pot conține doar litere care fac parte din secțiunea de litere Unicode, cifre arabe, cratime, litere de subliniere. , puncte. Deoarece literele nu se limitează doar la caractere ASCII, literele din orice limbă pot fi folosite în nume.
O declarație XML specifică versiunea lingvistică în care este scris documentul. Deoarece interpretarea conținutului unui document depinde de versiunea limbii, specificația prescrie să înceapă documentul cu o declarație XML. În prima versiune (1.0) a limbii, utilizarea declarației a fost opțională, în versiunile ulterioare este obligatorie. Astfel, versiunea lingvistică este determinată din declarație, iar dacă nu există declarație, se presupune versiunea 1.0.
Pe lângă versiunea XML, declarația poate conține și informații despre codificarea documentului și „dacă documentul ar trebui să rămână cu propriul DTD sau cu unul inclus”.
Exemplu:
<?xml version="1.1" encoding="UTF-8" ?>sau:
<?xml version="1.0" encoding="windows-1251"?>În toate aceste exemple, lipsea atributul „autonom”, care determină doar dacă să includă descrieri de markup în document din exterior. Setarea implicită la „nu”:
<?xml version="1.0" encoding="windows-1251" standalone="no"?>dacă documentul XML face referire la alte DTD-uri care descriu ce poate conține documentul, trebuie să specificațistandalone="no"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>dacă documentul XML nu se referă la alte fișiere și va folosi propriul DTD, trebuie să specificațistandalone="yes"
Declarație tip documentExistă o instrucțiune specială pentru declararea unui tip de document !DOCTYPE. Vă permite să specificați, folosind limbajul DTD, ce elemente sunt incluse în document, care sunt atributele acestora, ce entități pot fi utilizate și altceva.
De exemplu, iată documentul corect:
<?xml version="1.0"?> <salutare> Bună ziua, lume! </salutare>Are un element rădăcină <greeting>Hello, world!</greeting>și, în mod logic, documentul există. Totuși, nu este valabil ( ing. invalid ) [8] .
Cu ajutorul unei declarații de tip de document (DTD), este posibil să se descrie conținutul și structura logică a acestuia, precum și să se asocieze o pereche nume-valoare cu un anumit element. Iată cum arată prologul în intrarea Backus-Naur [9] :
prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' VersionInfo ::= S 'versiune' Eq ("'" VersionNum "'" | '"' VersionNum '"') Eq ::= S? '='S? VersionNum ::= '1.' [0-9]+ Diverse ::= Comentariu | PI | S doctypedecl ::= '<!DOCTYPE' S Nume (S ExternalID)? S? ('[' intSubset ']' S?)? '>' DeclSep ::= PEReferință | S intSubset ::= (markupdecl | DeclSep)* markupdecl ::= elementdecl | AttlistDecl | EntityDecl | Notație Decl | PI | cometariu extSubset ::= TextDecl? extSubsetDecl extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)*Declarația XML poate fi urmată de comentarii, instrucțiuni de procesare sau spații goale [10] , dar apoi vine Declarațiile de tip de document, unde „Nume” este numele etichetei rădăcină , „ExternalID” este identificatorul extern și „intSubset” este declarația de markup sau, altfel, referința la entitate. După cum spune specificația, dacă un identificator extern este declarat împreună cu o declarație internă, atunci aceasta din urmă vine înaintea primei [11] .
De exemplu:
<?xml version="1.0"?> <!DOCTYPE greeting SYSTEM "hello.dtd"> <greeting> Bună, lume! </salutare>Aici „ SYSTEM "hello.dtd"” este un identificator extern: adresa „hello.dtd” vă permite să utilizați datele din documentul „hello.dtd” ca declarații de markup.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE salut [ <!ELEMENT greeting (#PCDATA)> ]> <felicitare> Bună, lume! </salutare>Aici marcajul a fost declarat local în !DOCTYPE.
Instrucțiune de procesareInstrucțiuni de procesare ( ing. instrucțiuni de procesare, PI ), vă permit să plasați instrucțiuni pentru aplicații în document. Următorul exemplu arată o instrucțiune de procesare xml-stylesheet care transmite instrucțiunile din fișierul my-style.css unei aplicații xml-stylesheet (cum ar fi un browser) prin atributul href:
<?xml-stylesheet type="text/css" href="my-style.css"?> ComentariuComentariile ( ing. comentariu ) nu se referă la datele de caractere ale documentului. Comentariul începe cu secvența „<!--” și se termină cu secvența „-->”, combinația de caractere „--” nu poate apărea în interior. Caracterul & nu este folosit ca marcaj în interiorul unui comentariu.
Exemplu:
<!-- acesta este un comentariu -->Un element este un concept al structurii logice a unui document. Fiecare document conține unul sau mai multe elemente. Granițele elementelor sunt reprezentate de etichete de început și de sfârșit . Numele elementului din etichetele de început și de sfârșit ale elementului trebuie să se potrivească. Un element poate fi reprezentat și printr -o etichetă de element goală , adică care nu include alte elemente și date de caractere.
Tag ( eticheta engleză ) este o construcție de marcare care conține numele unui element.
Eticheta de pornire: <element1>
Etichetă de final: </element1>
Etichetă de element goală: <empty_element1 />
Într-un element, atributele pot fi utilizate numai în eticheta de început și eticheta de element goală.
Un exemplu de rețetă marcată cu XML:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE recipe> <recipe name= "bread" preptime= "5min" cooktime= "180min" > <titlu> pâine simplă </title> <composition> <ingredient amount= "3" unit= "glass" > Făină </ingredient> <ingredient amount= "0,25" unit= "gram" > Drojdie </ingredient> <ingredient amount= "1,5" unit= "sticlă" > Apă caldă </ingredient> </composition> <instructions> <step> Se amestecă toate ingredientele și se frământă bine. </step> <step> Închideți cu o cârpă și lăsați timp de o oră într-o cameră caldă. </step> <!-- <step> Citiți ziarul de ieri. </step> este un pas dubios... --> <step> Se framanta din nou, se pune pe o tava de copt si se da la cuptor. </step> </instructions> </recipe> Secțiunea CDATASecțiunea CDATA nu este o unitate logică de text. O secțiune poate apărea oriunde într-un document unde sintaxa permite plasarea datelor de caractere. Secțiunea începe <![CDATA[și se termină ]]>. Între acest marcaj sunt date de caractere; datele de caractere includ astfel caracterele < > &în forma lor imediată.
Un document bine format respectă toate regulile generale de sintaxă XML aplicabile oricărui document XML : structură corectă a documentului, nume care se potrivesc în eticheta elementului de început și de sfârșit etc. Un document care nu este bine format nu poate fi considerat un document xml.
Exemplu de document:
<?xml version="1.0" encoding="UTF-8"?> <!-- ecran de conectare --> <edsscript> <sequence name= "start" > <action cmd= "triggeron" > bt* </action> <action cmd= "triggeron" > msg_generic </action> <action cmd= "disablenbb" > toate </action> <action cmd= "setscrtext" > @@Sistem Giris@@ </action> <action cmd= "enablenbb" > înainte, meniul principal </action> <action cmd= "switchmsgtarget" > LOGIN_DLG </action> <action cmd= "sendmsg" > start </action> <action cmd= "sări" > pasul 2 </action> </sequence> <sequence name= "step2" > <action cmd= "waittrigger" > btnforward </action> <action cmd= "triggeron" > Autentificare* </action> <action cmd= "disablenbb" > toate </action> <action cmd= "sendmsg" > Verifica </action> </sequence> <trigger name= "login_succeded" > <condition type= "appmsg" > login_succeeded </condition> <sequence> <action cmd= "endscript" /> </sequence> </trigger> <trigger name= "login_unknownuser" > <condition type= "appmsg" > login_unknownuser </condition> <sequence name= "login_unknownuser" > <action cmd= "disablenbb" > toate </action> <action cmd= "setscrtext" > @@hata@@ </action> <action cmd= "showhtml" > generic_neg.htm,@@Yanlış kullanıcı ismi@@,@@Lütfen kullanıcı ismini doğru giriniz.@@ </action> <action cmd= "enablenbb" > înapoi </action> <action cmd= "waittrigger" > btnback </action> <action cmd= "sări" > start </action> </sequence> </trigger> <trigger name= "login_incorrectpwd" > <condition type= "appmsg" > login_incorrectpwd </condition> <sequence name= "login_incorrectpwd" > <action cmd= "disablenbb" > toate </action> <action cmd= "setscrtext" > @@hata@@ </action> <action cmd= "showhtml" > generic_neg.htm,@@Hatalı parola@@,@@Lütfen parolanızı doğru giriniz.@@ </action> <action cmd= "enablenbb" > înapoi </action> <action cmd= "waittrigger" > btnback </action> <action cmd= "sări" > start </action> </sequence> </trigger> <!-- generic triggers --> <trigger name= "btnback" > <condition type= "buttonclick" > înapoi </condition> <sequence name= "btnback" > <action cmd= "triggeron" > btnback </action> </sequence> </trigger> <trigger name= "btnforward" > <condition type= "buttonclick" > redirecţiona </condition> <sequence name= "btnforward" > <action cmd= "triggeron" > btnforward </action> </sequence> </trigger> <trigger name= "btnmainmenu" > <condition type= "buttonclick" > meniu principal </condition> <sequence> <action cmd= "jumpscript" > <value label= "mainmenuscript" scope= "local" /> </action> </sequence> </trigger> <trigger name= "btnquitapp" > < tipul de condiție = „buttonclick” > renunta la aplicare </condition> <sequence name= "btnquitapp" > <action cmd= "callscript" > quitapp.xml </action> <action cmd= "sări" > start </action> </sequence> </trigger> <trigger name= "error_generic" > <condition type= "appmsg" > eroare* </condition> <sequence> <action cmd= "showhtml" > errdsc_null.htm,@@Hata@@ </action> <action cmd= "disablenbb" > toate </action> <action cmd= "enablenbb" > redirecţiona </action> <action cmd= "waittrigger" > btnforward </action> <action cmd= "endscript" /> </sequence> </trigger> <trigger name= "msg_generic" > <condition type= "appmsg" > msg_generic </condition> <sequence> <action cmd= "showhtml" > generic_msg.htm </action> <action cmd= "triggeron" > msg_generic </action> </sequence> </trigger> <!-- O excepție netratată este aruncată din partea codului hard. --> <trigger name= "error_hardcodeside" > <condition type= "appmsg" > error_hardcodeside </condition> <sequence> <action cmd= "triggeroff" > * </action> <action cmd= "triggeron" > btnmainmenu </action> <action cmd= "triggeron" > btnquitapp </action> <action cmd= "disablenbb" > toate </action> <action cmd= "enablenbb" > meniu principal </action> <action cmd= "showhtml" > errdsc_null.htm,Hata, @@İşlem sırasında bir hata meydana geldi.@@ </action> <action cmd= "waittrigger" > btnmainmenu </action> </sequence> </trigger> </edscript>Această secțiune conține un rezumat al unora dintre prevederile recomandărilor W3C legate de lucrul cu documente. Recomandările corespunzătoare se pot aplica atât documentelor XML, cât și clasei mai largi de documente. De obicei, sunt furnizate link-uri către instrumentele de gestionare a documentelor recomandate de W3C.
Specificația necesită ca procesoarele să accepte cel puțin două codificări Unicode: UTF-8 și UTF-16 .
Specificația XML definește conceptele unui procesor XML și o aplicație . Un procesor XML ( parser ) este un program care analizează marcajul și transmite informații despre structura unui document către un alt program, o aplicație.
Specificația XML impune anumite cerințe procesorului fără a afecta cerințele aplicației.
Un document este valabil dacă are asociată o definiție a tipului de document și dacă documentul respectă constrângerile prezentate în definiția tipului de document.
Procesoarele XML sunt împărțite în două clase: validare și nevalidare.
Procesatorii de validare verifică valabilitatea documentului și trebuie să raporteze (la alegerea utilizatorului) încălcările constrângerilor menționate în definiția tipului de document.
Procesatorii care nu validează nu verifică valabilitatea documentului, dar sarcinile de preprocesare a documentelor menționate mai sus le rămân.
Limbajele de schemă sunt folosite pentru a descrie tipurile de documente . Deoarece XML este un subset al limbajului SGML , moștenește limbajul Document Type Definition ( DTD ) dezvoltat pentru SGML. Ulterior, au fost dezvoltate și alte limbaje de schemă, cel mai cunoscut fiind XML Schema , RELAX NG .
XSLT este conceput pentru a rezolva problema transformării unui document XML într-o altă schemă sau alt format .
Pentru un document formatat (un document pregătit pentru randare), formatul XSL-FO este destinat .
XPath este o sintaxă pentru adresarea conținutului unui document reprezentat sub formă de arbore. Expresiile XPath sunt folosite în limbajul XQuery . Expresiile XPath pot fi utilizate în general în orice context în care este adecvat să se utilizeze referințe formale la elementele arborelui, în special ca parametri ai metodelor de interfețe de acces la documente.
XQuery este un limbaj de programare orientat spre documente.
Există trei opțiuni API pentru citirea XML [12] .
API de evenimente ( API -ul de evenimente, API-ul de tip push ) - procesorul XML citește XML; la un anumit eveniment (apariția unei etichete de deschidere sau de închidere, șir de text, atribut), este apelată funcția de apel invers .
Stream API (de asemenea, pull-style API ) - aranjat în maniera fluxurilor I/O . Codul aplicației cere procesorului părți din XML, care se pot deplasa înainte doar prin XML, uitând părțile deja trecute.
Object API ( Document Object Model , DOM, „document object model”) - citește XML și îl recreează în memorie ca structură de obiect.
Există și API-uri hibride: părțile externe și neimportante sunt citite prin metoda stream, în timp ce părțile interne și importante sunt citite prin metoda obiect.
Exemplu de cod (C++, API fictiv) xml :: Cititor StreamReader ( "in.xml" ); std :: nume șir , valoare ; cititor . enterTag ( "document" ); în timp ce ( cititor . getTag ( „lucru” ) { xml :: Element * elThing = cititor . readEntireSubtree (); lucruri . plasează_înapoi (); Lucru și lucru = lucruri . spate (); lucru . nume = elThing . requireStringAttr ( "nume" ); lucru . valoare = elThing . text (); }API-ul Direct Write scrie etichetă XML cu etichetă, atribut cu atribut.
Object API alias Document Object Model .
XML are implementări de parser pentru toate limbajele de programare moderne [17] .
Fără utilizarea CSS sau XSL , documentul XML este redat ca text simplu în majoritatea browserelor web. Unele browsere, cum ar fi Internet Explorer , Mozilla Firefox și Opera ( instrumentul Dragonfly încorporat în Opera ) afișează structura documentului ca un arbore, permițând restrângerea și extinderea nodurilor cu clicuri de mouse.
Aplicarea stilurilor CSSProcesul este similar cu aplicarea CSS unui document HTML pentru afișare. Pentru a aplica CSS atunci când este afișat într-un browser, documentul XML trebuie să conțină un link special către foaia de stil. De exemplu:
<?xml-stylesheet type="text/css" href="myStyleSheet.css"?>Aceasta este diferită de abordarea HTML, care utilizează elementul <link>.
Aplicarea transformărilor în format XSL-FOBrowserele moderne se numără printre instrumentele care pot efectua transformări XSLT. În browser, o astfel de transformare este de obicei efectuată pentru a formata documentul (conversia documentului în format XSL-FO). Următoarea declarație din prologul documentului XML instruiește browserul să efectueze transformarea XSLT descrisă în fișierul transform.xsl:
<?xml-stylesheet type="text/xsl" href="transform.xsl"?>Puteți lucra cu un document XML într-un editor de text obișnuit, dar editorii obișnuiți nu acceptă structura documentului. Există editori XML speciali care fac lucrul cu un document mai convenabil și mai eficient.
Sistemul de management al bazei de date DB2 vă permite să stocați date în format XML și oferă acces la astfel de date folosind limbajul XQuery.
XML este suportat la nivelurile scăzute de hardware, firmware și software în soluțiile hardware moderne [18] .
XML este un limbaj de marcare, cu alte cuvinte, un mijloc de descriere a unui document. Este în nișa documentelor, textelor, unde ponderea datelor de caractere eterogene este mare, iar cota de markup este mică - XML are succes. Pe de altă parte, schimbul de date în sisteme deschise nu se limitează la schimbul de documente. Redundanța marcajului XML (și în scopuri de proiectare a limbajului, se precizează în mod explicit că concizia nu este o prioritate a proiectului) afectează situațiile în care datele nu se încadrează în modelul tradițional de document. Un flux de știri, de exemplu, formatat folosind sintaxa XML ( RSS , formate Atom ), nu este un document în sensul tradițional, ci un flux de același tip de mini-documente - marcajul verbos și redundant în acest caz este o parte esențială a datelor transmise.
W3C este preocupat de eficacitatea XML, iar grupurile de lucru relevante analizează această problemă (de la începutul anului 2013, nu au fost elaborate documente normative).
O altă situație în care formatele XML ar putea să nu fie cea mai bună soluție este atunci când lucrați cu date cu o structură simplă și o cantitate mică de date de caractere (câmpuri de date). În acest caz, ponderea markupului în volumul total este mare, iar procesarea programatică a XML poate fi nerezonabil de costisitoare în comparație cu lucrul cu date cu o structură mai simplă. În acest domeniu, dezvoltatorii se uită la instrumente native orientate spre date, cum ar fi INI , YAML , JSON .
W3C lucrează la crearea unui limbaj de scripting pentru lucrul cu XML (până la începutul anului 2013 nu au fost elaborate documente de reglementare).
Consorțiul World Wide Web (W3C) | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Produse și standarde |
| ||||||||||||||
Organizații |
| ||||||||||||||
PE |
| ||||||||||||||
Conferințe |
|
web semantic | |
---|---|
Bazele | |
Subsecțiuni |
|
Aplicații |
|
subiecte asemănătoare | |
Standarde |
|
Web și site-uri web | |
---|---|
la nivel global | |
La nivel local | |
Tipuri de site-uri și servicii |
|
Creare si intretinere | |
Tipuri de machete, pagini, site-uri | |
Tehnic | |
Marketing | |
Societate și cultură |
Limbaje de marcare a documentelor | |
---|---|
documente de birou | |
bine cunoscute | |
Mai puțin cunoscut |