Attributo XML vs elemento XML


253

Al lavoro ci viene chiesto di creare file XML per passare i dati a un'altra applicazione offline che creerà quindi un secondo file XML da restituire per aggiornare alcuni dei nostri dati. Durante il processo abbiamo discusso con il team dell'altra applicazione sulla struttura del file XML.

Il campione che ho trovato è essenzialmente qualcosa di simile:

<INVENTORY>
   <ITEM serialNumber="something" location="something" barcode="something">
      <TYPE modelNumber="something" vendor="something"/> 
   </ITEM>
</INVENTORY>

L'altro team ha affermato che questo non era uno standard industriale e che gli attributi dovevano essere usati solo per i metadati. Hanno suggerito:

<INVENTORY>
   <ITEM>
      <SERIALNUMBER>something</SERIALNUMBER>
      <LOCATION>something</LOCATION>
      <BARCODE>something</BARCODE>
      <TYPE>
         <MODELNUMBER>something</MODELNUMBER>
         <VENDOR>something</VENDOR>
      </TYPE>
   </ITEM>
</INVENTORY>

Il motivo per cui ho suggerito il primo è che la dimensione del file creato è molto più piccola. Ci saranno circa 80000 elementi che saranno nel file durante il trasferimento. Il loro suggerimento in realtà risulta essere tre volte più grande di quello che ho suggerito. Ho cercato il misterioso "standard industriale" che è stato menzionato, ma il più vicino che ho trovato è stato che gli attributi XML dovevano essere usati solo per i metadati, ma ho detto che il dibattito riguardava quelli che in realtà erano metadati.

Dopo la spiegazione lunga (scusa) come si determina cosa sono i metadati e quando si progetta la struttura di un documento XML come si deve decidere quando utilizzare un attributo o un elemento?


4
Ho trovato questa risorsa davvero buona: ibm.com/developerworks/xml/library/x-eleatt.html
Laurens Holst,

5
+1 per "... il dibattito riguardava quelli che in realtà erano metadati".
Ritirato il

Nota i nomi dei tag in minuscolo con trattini: stackoverflow.com/questions/1074447/…
Ben

Risposte:


145

Uso questa regola empirica:

  1. Un attributo è qualcosa che è autonomo, cioè un colore, un ID, un nome.
  2. Un elemento è qualcosa che ha o potrebbe avere attributi propri o contenere altri elementi.

Quindi il tuo è vicino. Avrei fatto qualcosa del tipo:

EDIT : aggiornato l'esempio originale in base al feedback di seguito.

  <ITEM serialNumber="something">
      <BARCODE encoding="Code39">something</BARCODE>
      <LOCATION>XYX</LOCATION>
      <TYPE modelNumber="something">
         <VENDOR>YYZ</VENDOR>
      </TYPE>
   </ITEM>

22
Ho letto alcune delle risposte e qualcosa che non è stato sottolineato abbastanza dalla mia esperienza è che se i tuoi dati in un "attributo" e improvvisamente hanno un> o <il tuo documento XML si romperà penso che ci siano cinque caratteri ASCII (>, <, &,?, ") che lo ucciderà. Se questo carattere speciale fosse in un elemento, puoi semplicemente aggiungere alcuni tag CDATA attorno a questi dati. Direi, usa gli attributi solo quando sai al 100% quali valori metteranno lì dentro, ad esempio un numero intero o una data, probabilmente tutto ciò che è generato dal computer. Se il codice a barre è stato generato da un essere umano, non dovrebbe essere un attributo.
John Ballinger,

39
Davvero in ritardo alla festa, ma lo speciale argomento del carattere ASCII è sbagliato: questo è lo scopo dell'evasione, sia per gli attributi che per i dati di testo.
micahtan,

2
@donroby - Mi dispiace, sarebbe il mio errore nel comunicare. Per fuga, intendo la codifica XML. '<' = & lt; ecc. Mi sembra strano decidere tra un attributo o un elemento in base ai caratteri che compongono il contenuto anziché al significato del contenuto.
micahtan,

3
@donroby: non è corretto. Il testo sostitutivo di &lt;is &#60;, che è un riferimento di carattere, non un riferimento di entità. &lt;è OK negli attributi. Vedi: w3.org/TR/REC-xml/#sec-predefined-ent
porges

14
@John: se questo è un problema, allora c'è qualcosa nella tua toolchain che non produce XML valido. Non penso che questo sia un motivo per scegliere tra attributi o elementi. (Inoltre, non è possibile "semplicemente aggiungere tag CDATA" attorno all'input dell'utente perché potrebbe contenere ]]>!)
porges

48

Alcuni dei problemi con gli attributi sono:

  • gli attributi non possono contenere più valori (gli elementi figlio possono)
  • gli attributi non sono facilmente espandibili (per modifiche future)
  • gli attributi non possono descrivere le strutture (gli elementi figlio possono)
  • gli attributi sono più difficili da manipolare dal codice del programma
  • i valori degli attributi non sono facili da testare con un DTD

Se usi gli attributi come contenitori per i dati, finisci con i documenti che sono difficili da leggere e conservare. Prova a usare gli elementi per descrivere i dati. Utilizzare gli attributi solo per fornire informazioni non pertinenti ai dati.

Non finire così (non è così che XML dovrebbe essere usato):

<note day="12" month="11" year="2002" 
      to="Tove" to2="John" from="Jani" heading="Reminder"  
      body="Don't forget me this weekend!"> 
</note>

Fonte: http://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp


2
Il primo punto è errato, vedi: w3.org/TR/xmlschema-2/#derivation-by-list
porges

6
Direi che il primo punto è corretto ed listè una soluzione parziale a questo problema. Non ci possono essere più attributi con lo stesso nome. Con l' listattributo ha ancora un solo valore, che è un elenco separato da spazi bianchi di alcuni tipi di dati. I caratteri di separazione sono fissi, quindi non è possibile avere più valori se un singolo valore del tipo di dati desiderato può contenere spazi bianchi. Ciò esclude la possibilità di avere, ad esempio, più indirizzi in un attributo "indirizzo".
Jasso,

7
'Gli attributi sono più difficili da manipolare dal codice del programma' - Non posso essere d'accordo con quello. In effetti ho trovato il contrario per essere vero. Non è abbastanza per affermare davvero in entrambi i casi.
Paul Alexander

4
Aggiungo anche che la convalida contro un DTD non è più veramente rilevante, con XML-Schema, Schematron e Relax, et. al. il tutto fornendo metodi molto più potenti e in alcuni casi più intuitivi per la convalida dei documenti XML. Inoltre, W3Schools è un riferimento davvero scarso per qualsiasi cosa

37

"XML" sta per "eXtensible Markup Language". Un linguaggio di markup implica che i dati sono testo, contrassegnato da metadati sulla struttura o sulla formattazione.

XHTML è un esempio di XML utilizzato nel modo in cui era inteso:

<p><span lang="es">El Jefe</span> insists that you
    <em class="urgent">MUST</em> complete your project by Friday.</p>

Qui, la distinzione tra elementi e attributi è chiara. Gli elementi di testo vengono visualizzati nel browser e gli attributi sono istruzioni su come visualizzarli (anche se ci sono alcuni tag che non funzionano in questo modo).

La confusione sorge quando XML non viene utilizzato come linguaggio di markup, ma come linguaggio di serializzazione dei dati , in cui la distinzione tra "dati" e "metadati" è più vaga. Quindi la scelta tra elementi e attributi è più o meno arbitraria, tranne per le cose che non possono essere rappresentate con gli attributi (vedi la risposta di feenster).


32

Elemento XML vs attributo XML

XML si basa sull'accordo. Per prima cosa, rimanda a eventuali schemi XML esistenti o convenzioni stabilite all'interno della tua comunità o industria.

Se sei veramente in una situazione per definire il tuo schema da zero, ecco alcune considerazioni generali che dovrebbero informare la decisione tra elemento e attributo :

<versus>
  <element attribute="Meta content">
    Content
  </element>
  <element attribute="Flat">
    <parent>
      <child>Hierarchical</child>
    </parent>
  </element>
  <element attribute="Unordered">
    <ol>
      <li>Has</li>
      <li>order</li>
    </ol>
  </element>
  <element attribute="Must copy to reuse">
    Can reference to re-use
  </element>
  <element attribute="For software">
    For humans
  </element>
  <element attribute="Extreme use leads to micro-parsing">
    Extreme use leads to document bloat
  </element>
  <element attribute="Unique names">
    Unique or non-unique names
  </element>
  <element attribute="SAX parse: read first">
    SAX parse: read later
  </element>
  <element attribute="DTD: default value">
    DTD: no default value
  </element>
</versus>

23

Potrebbe dipendere dal tuo utilizzo. L'XML utilizzato per rappresentare i dati strutturati generati da un database potrebbe funzionare bene con valori di campo posizionati come attributi.

Tuttavia, l'XML usato come trasporto di messaggi sarebbe spesso meglio usare più elementi.

Ad esempio, supponiamo di avere questo XML come proposto nella risposta:

<INVENTORY>
   <ITEM serialNumber="something" barcode="something">
      <Location>XYX</LOCATION>
      <TYPE modelNumber="something">
         <VENDOR>YYZ</VENDOR>
      </TYPE>
    </ITEM>
</INVENTORY>

Ora vogliamo inviare l'elemento ITEM a un dispositivo per stampare il codice a barre, tuttavia è possibile scegliere tra diversi tipi di codifica. Come rappresentiamo il tipo di codifica richiesto? Improvvisamente ci rendiamo conto, in qualche modo tardivamente, che il codice a barre non era un singolo valore automatico, ma potrebbe essere qualificato con la codifica richiesta durante la stampa.

   <ITEM serialNumber="something">
      <barcode encoding="Code39">something</barcode>
      <Location>XYX</LOCATION>
      <TYPE modelNumber="something">
         <VENDOR>YYZ</VENDOR>
      </TYPE>
   </ITEM>

Il punto è che a meno che non si costruisca una sorta di XSD o DTD insieme a uno spazio dei nomi per fissare la struttura in pietra, si potrebbe essere meglio serviti lasciando aperte le opzioni.

XML IMO è al massimo utile quando può essere flesso senza rompere il codice esistente che lo utilizza.


Buon punto sul "codice a barre", ho affrettato il mio esempio e l'avrei sicuramente suddiviso nel suo elemento. Anche un buon punto su XSD / DTD.
Chuck,

10

Uso le seguenti linee guida nel mio schema per quanto riguarda gli attributi rispetto agli elementi:

  • Usa gli elementi per il testo a esecuzione prolungata (in genere quelli di tipo stringa o normalizzato)
  • Non utilizzare un attributo se esiste un raggruppamento di due valori (ad esempio eventStartDate ed eventEndDate) per un elemento. Nell'esempio precedente, dovrebbe esserci un nuovo elemento per "evento" che può contenere gli attributi startDate e endDate.
  • Data, ora e data di lavoro (ad es. Conteggi, importo e tariffa) dovrebbero essere elementi.
  • Gli elementi temporali non aziendali come l'ultimo aggiornamento, scaduto il, dovrebbero essere attributi.
  • I numeri non commerciali come i codici hash e gli indici dovrebbero essere attributi. * Usa gli elementi se il tipo sarà complesso.
  • Utilizzare gli attributi se il valore è un tipo semplice e non si ripete.
  • xml: id e xml: lang devono essere attributi che fanno riferimento allo schema XML
  • Preferire gli attributi quando tecnicamente possibile.

La preferenza per gli attributi è che fornisce quanto segue:

  • unico (l'attributo non può apparire più volte)
  • l'ordine non ha importanza
  • le proprietà sopra sono ereditabili (questo è qualcosa che il modello di contenuto "all" non supporta nel linguaggio dello schema corrente)
  • il vantaggio è che sono meno dettagliati e consumano meno larghezza di banda, ma questo non è davvero un motivo per preferire gli attributi agli elementi.

Ho aggiunto quando tecnicamente possibile perché ci sono momenti in cui l'uso degli attributi non è possibile. Ad esempio, le opzioni di set di attributi. Ad esempio, utilizzare (startDate e endDate) xor (startTS e endTS) non è possibile con la lingua dello schema corrente

Se lo schema XML inizia a consentire la limitazione o l'estensione del modello di contenuto "all", probabilmente lo lascerei cadere


8

In caso di dubbio, KISS : perché mescolare attributi ed elementi quando non si ha un motivo chiaro per usare gli attributi. Se in seguito decidi di definire un XSD, anche questo finirà per essere più pulito. Quindi, anche se in seguito deciderai di generare una struttura di classe dal tuo XSD, sarà anche più semplice.


8

Non esiste una risposta universale a questa domanda (sono stato fortemente coinvolto nella creazione delle specifiche del W3C). L'XML può essere utilizzato per molti scopi: documenti di testo, dati e codice dichiarativo sono tre dei più comuni. Lo uso anche molto come modello di dati. Ci sono aspetti di queste applicazioni in cui gli attributi sono più comuni e altri in cui gli elementi figlio sono più naturali. Esistono anche funzionalità di vari strumenti che ne semplificano o rendono più difficile l'utilizzo.

XHTML è un'area in cui gli attributi hanno un uso naturale (es. In class = 'pippo'). Gli attributi non hanno alcun ordine e questo potrebbe rendere più semplice per alcune persone sviluppare strumenti. Gli attributi OTOH sono più difficili da digitare senza uno schema. Trovo anche che gli attributi spaziati (foo: bar = "zork") siano spesso più difficili da gestire in vari set di strumenti. Dai un'occhiata ad alcuni dei linguaggi W3C per vedere la miscela comune. SVG, XSLT, XSD, MathML sono alcuni esempi di linguaggi noti e tutti hanno una ricca offerta di attributi ed elementi. Alcune lingue consentono anche più di un modo per farlo, ad es

<foo title="bar"/>;

o

<foo>
  <title>bar</title>;
</foo>;

Si noti che questi NON sono equivalenti sintatticamente e richiedono un supporto esplicito negli strumenti di elaborazione)

Il mio consiglio sarebbe quello di dare un'occhiata alla pratica comune nell'area più vicina alla tua applicazione e considerare anche quali set di strumenti potresti voler applicare.

Infine, assicurati di differenziare gli spazi dei nomi dagli attributi. Alcuni sistemi XML (ad esempio Linq) rappresentano gli spazi dei nomi come attributi nell'API. IMO questo è brutto e potenzialmente confuso.


6

Altri hanno spiegato come differenziare gli attributi dagli elementi, ma da una prospettiva più generale, mettere tutto negli attributi perché riduce l'XML risultante è sbagliato.

XML non è progettato per essere compatto ma per essere portatile e leggibile dall'uomo. Se si desidera ridurre la dimensione dei dati in transito, utilizzare qualcos'altro (come i buffer di protocollo di Google ).


Testo XML più piccolo è più leggibile dall'uomo solo perché è più piccolo!
Nashev,

5

la domanda da un milione di dollari!

prima di tutto, non preoccuparti troppo delle prestazioni ora. rimarrai stupito dalla rapidità con cui un parser XML ottimizzato eseguirà il ripping del tuo XML. ancora più importante, qual è il tuo progetto per il futuro: man mano che l'XML si evolve, come manterrai l'accoppiamento e l'interoperabilità lenti?

più concretamente, puoi rendere il modello di contenuto di un elemento più complesso ma è più difficile estendere un attributo.


5

Entrambi i metodi per la memorizzazione delle proprietà dell'oggetto sono perfettamente validi. Dovresti discostarti da considerazioni pragmatiche. Prova a rispondere alla seguente domanda:

  1. Quale rappresentazione porta ad un'analisi dei dati più veloce \ generazione?

  2. Quale rappresentazione porta a un trasferimento più veloce dei dati?

  3. La leggibilità è importante?

    ...


5

Usa gli elementi per i dati e gli attributi per i metadati (dati sui dati dell'elemento).

Se un elemento viene visualizzato come predicato nelle stringhe selezionate, hai un buon segno che dovrebbe essere un attributo. Allo stesso modo se un attributo non viene mai usato come predicato, allora forse non sono utili metadati.

Ricorda che l'XML dovrebbe essere leggibile dalla macchina e non leggibile dall'uomo e per i documenti di grandi dimensioni l'XML si comprime molto bene.


4

È discutibile in entrambi i casi, ma i tuoi colleghi hanno ragione nel senso che l'XML dovrebbe essere usato per "markup" o metadati attorno ai dati reali. Da parte tua, hai ragione nel dire che a volte è difficile decidere dove si trova la linea tra metadati e dati quando si modella il tuo dominio in XML. In pratica, ciò che faccio è fingere che qualsiasi cosa nel markup sia nascosta e che siano leggibili solo i dati al di fuori del markup. Il documento ha un senso in quel modo?

XML è notoriamente ingombrante. Per il trasporto e lo stoccaggio, la compressione è altamente raccomandata se puoi permetterti la potenza di elaborazione. XML si comprime bene, a volte in modo fenomenale, a causa della sua ripetitività. Ho fatto comprimere file di grandi dimensioni a meno del 5% delle loro dimensioni originali.

Un altro punto per rafforzare la tua posizione è che mentre l'altro team sta discutendo dello stile (in quanto la maggior parte degli strumenti XML gestirà un documento con tutti gli attributi con la stessa facilità di un documento PCDATA tutto #) stai discutendo di praticità. Mentre lo stile non può essere totalmente ignorato, i meriti tecnici dovrebbero avere più peso.


4

È in gran parte una questione di preferenza. Uso Elements per raggruppamento e attributi per i dati, ove possibile, poiché vedo questo come più compatto dell'alternativa.

Ad esempio preferisco .....

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
         <person name="Rory" surname="Becker" age="30" />
        <person name="Travis" surname="Illig" age="32" />
        <person name="Scott" surname="Hanselman" age="34" />
    </people>
</data>

...Invece di....

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
        <person>
            <name>Rory</name>
            <surname>Becker</surname>
            <age>30</age>
        </person>
        <person>
            <name>Travis</name>
            <surname>Illig</surname>
            <age>32</age>
        </person>
        <person>
            <name>Scott</name>
            <surname>Hanselman</surname>
            <age>34</age>
        </person>
    </people>
</data>

Tuttavia, se ho dati che non rappresentano facilmente all'interno di diciamo 20-30 caratteri o contengono molte virgolette o altri caratteri che devono essere evasi, direi che è tempo di scomporre gli elementi ... possibilmente con blocchi CData.

<?xml version="1.0" encoding="utf-8"?>
<data>
    <people>
        <person name="Rory" surname="Becker" age="30" >
            <comment>A programmer whose interested in all sorts of misc stuff. His Blog can be found at http://rorybecker.blogspot.com and he's on twitter as @RoryBecker</comment>
        </person>
        <person name="Travis" surname="Illig" age="32" >
            <comment>A cool guy for who has helped me out with all sorts of SVn information</comment>
        </person>
        <person name="Scott" surname="Hanselman" age="34" >
            <comment>Scott works for MS and has a great podcast available at http://www.hanselminutes.com </comment>
        </person>
    </people>
</data>

2
Temo che questo sia completamente sbagliato - dovresti seguire le linee guida del W3C: w3schools.com/DTD/dtd_el_vs_attr.asp - L'XML non dovrebbe essere formato sulla leggibilità o sul renderlo "compatto" - ma piuttosto usare elementi o attributi correttamente allo scopo per cui sono stati progettati.
Vidar,

24
Mi dispiace, ma questo è fuorviante. La pagina W3schools non è una guida W3C. La raccomandazione W3C XML (di cui ero un partecipante) consente di utilizzare elementi e attributi in base alle esigenze e agli stili degli utenti.
peter.murray.rust,

4

Che ne dite di sfruttare la nostra intuizione dell'orientamento agli oggetti duramente guadagnata? Di solito trovo che sia semplice pensare quale sia un oggetto e quale sia un attributo dell'oggetto o a quale oggetto si riferisca.

Qualunque cosa abbia un senso intuitivo in quanto gli oggetti devono adattarsi come elementi. I suoi attributi (o proprietà) sarebbero attributi per questi elementi in xml o elemento figlio con attributo.

Penso che per casi più semplici come nell'esempio l'analogia dell'orientamento agli oggetti funzioni bene per capire quale sia l'elemento e quale sia l'attributo di un elemento.


2

Solo un paio di correzioni ad alcune informazioni negative:

@ John Ballinger: gli attributi possono contenere qualsiasi dato personaggio. <> & "'devono essere salvati a & lt; & gt; & amp; & quot; e & apos; rispettivamente. Se usi una libreria XML, te ne occuperà per te.

Inferno, un attributo può contenere dati binari come un'immagine, se proprio lo desideri, semplicemente codificandolo con base64 e rendendolo un dato: URL.

@feenster: gli attributi possono contenere più elementi separati da spazio nel caso di IDS o NAMES, che includono numeri. Nitpicky, ma questo può finire per risparmiare spazio.

L'uso degli attributi può mantenere XML competitivo con JSON. Vedi marcatura grassa: tagliare il mito della marcatura grassa una caloria alla volta .


Non solo ID o nomi. Possono contenere elenchi separati da spazi di qualsiasi cosa.
John Saunders,

@JohnSaunders IDS o NAMES sono tipi DTD specifici (anche schema XML, credo), supportati a basso livello dalla maggior parte dei processori XML. Se gestito dal livello applicazione anziché dalle librerie XML, qualsiasi tipo di dati carattere funziona (valori separati o altro).
brianary

Personalmente, solo perché puoi non significa che dovresti.
Lankymart,

1
@Lankymart Come ho già detto, stavo solo correggendo alcune informazioni errate (che per qualche motivo stava facendo un punteggio alto). I dati binari di solito non appartengono affatto all'XML.
brianary

1

Sono sempre sorpreso dai risultati di questo tipo di discussioni. Per me esiste una regola molto semplice per decidere se i dati appartengono a un attributo o come contenuto e cioè se i dati hanno una sottostruttura navigabile.

Ad esempio, il testo senza markup appartiene sempre agli attributi. Sempre.

Gli elenchi appartengono a sottostruttura o contenuto. Il testo che può includere nel tempo contenuti secondari strutturati incorporati appartiene al contenuto. (Nella mia esperienza c'è relativamente poco di questo - testo con markup - quando si utilizza XML per l'archiviazione o lo scambio di dati.)

Lo schema XML scritto in questo modo è conciso.

Ogni volta che vedo casi del genere <car><make>Ford</make><color>Red</color></car>, penso a me stesso "Accidenti, l'autore ha pensato che ci sarebbero stati sotto-elementi all'interno dell'elemento make?" <car make="Ford" color="Red" />è significativamente più leggibile, non c'è dubbio su come sarebbe gestito lo spazio bianco ecc.

Considerate solo le regole di gestione degli spazi bianchi, credo che questo fosse il chiaro intento dei progettisti XML.


una delle poche spiegazioni che posso leggere. non ho idea se sia una buona idea ... ma almeno capisco il punto;)
Thufir,

0

Questo è molto chiaro in HTML dove si possono vedere chiaramente le differenze di attributi e markup:

  1. Tutti i dati sono tra markup
  2. Gli attributi sono usati per caratterizzare questi dati (es. Formati)

Se hai solo dati puri come XML, c'è una differenza meno chiara. I dati potrebbero stare tra markup o come attributi.

=> La maggior parte dei dati dovrebbe essere compresa tra il markup.

Se vuoi usare gli attributi qui: puoi dividere i dati in due categorie: Dati e "metadati", dove i metadati non fanno parte del record, vuoi presentare, ma cose come "formato versione", "data di creazione" , eccetera.

<customer format="">
     <name></name>
     ...
</customer>

Si potrebbe anche dire: "Usa gli attributi per caratterizzare il tag, usa i tag per fornire i dati stessi".


-1

Sono d'accordo con feenster. Stai lontano dagli attributi se puoi. Gli elementi sono favorevoli all'evoluzione e più interoperabili tra i toolkit del servizio web. Non troverai mai questi toolkit che serializzano i tuoi messaggi di richiesta / risposta usando gli attributi. Questo ha anche senso poiché i nostri messaggi sono dati (non metadati) per un toolkit di servizi web.


-1

Attributi possono facilmente diventare difficili da gestire nel tempo fidati di me. sto sempre alla larga da loro personalmente. Gli elementi sono molto più espliciti e leggibili / utilizzabili sia dai parser che dagli utenti.

L'unica volta che li ho mai usati è stato definire l'estensione del file di un URL di asset:

<image type="gif">wank.jpg</image> ...etc etc

immagino che se conosci al 100% l'attributo non avrà bisogno di essere espanso potresti usarli, ma quante volte lo sai.

<image>
  <url>wank.jpg</url>
  <fileType>gif</fileType>
</image>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.