Was ist die richtige Darstellung von Null-XML-Elementen?

166

Ich habe nullElemente gesehen , die auf verschiedene Arten dargestellt wurden:

Das Element ist vorhanden mit xsi:nil="true":

 <book>
     <title>Beowulf</title>
     <author xsi:nil="true"/>
 </book>

Das Element ist vorhanden, wird aber als leeres Element dargestellt (was meiner Meinung nach seit 'leer' falsch ist und nullsemantisch unterschiedlich ist):

 <book>
     <title>Beowulf</title>
     <author/>
 </book>

 <!-- or: -->
 <book>
     <title>Beowulf</title>
     <author></author>
 </book>

Das Element ist im zurückgegebenen Markup überhaupt nicht vorhanden :

 <book>
     <title>Beowulf</title>
 </book>

Das Element hat ein <null/>untergeordnetes Element (von TStamper unten):

 <book>
     <title>Beowulf</title>
     <author><null/></author>
 </book>

Gibt es eine korrekte oder kanonische Möglichkeit, einen solchen nullWert darzustellen ? Gibt es zusätzliche Möglichkeiten als die obigen Beispiele?

Das XML für die obigen Beispiele ist erfunden, lesen Sie also nicht zu weit hinein. :) :)

Rob Hruska
quelle

Antworten:

121

xsi: nil ist der richtige Weg, um einen Wert so darzustellen, dass: Wenn der DOM Level 2-Aufruf getElementValue () ausgegeben wird, wird der NULL-Wert zurückgegeben. xsi: nil wird auch verwendet, um ein gültiges Element ohne Inhalt anzugeben, selbst wenn dieser Inhaltstyp normalerweise keine leeren Elemente zulässt.

Wenn ein leeres Tag verwendet wird, gibt getElementValue () die leere Zeichenfolge ("") zurück. Wenn das Tag weggelassen wird, ist kein Autoren-Tag vorhanden. Dies kann semantisch anders sein als das Setzen auf 'nil' (Bsp. Das Setzen von "Series" auf nil kann bedeuten, dass das Buch zu keiner Serie gehört, während das Weglassen von Serien bedeuten kann, dass Serien ein nicht anwendbares Element für das aktuelle Element sind.)

Von: Der W3C

XML-Schema: Structures führt einen Mechanismus ein, der signalisiert, dass ein Element als · gültig · akzeptiert werden soll, wenn es trotz eines Inhaltstyps, der keinen leeren Inhalt erfordert oder sogar unbedingt zulässt, keinen Inhalt hat. Ein Element kann ohne Inhalt gültig sein, wenn es das Attribut xsi: nil mit dem Wert true hat. Ein so beschriftetes Element muss leer sein, kann jedoch Attribute enthalten, wenn der entsprechende komplexe Typ dies zulässt.

Eine Klarstellung:
Wenn Sie ein Buch-XML-Element haben und eines der untergeordneten Elemente Buch: Serie ist, haben Sie beim Ausfüllen mehrere Optionen:

  1. Element vollständig entfernen - Dies kann erfolgen, wenn Sie angeben möchten, dass Serien nicht für dieses Buch gelten oder dass dieses Buch nicht Teil einer Serie ist. In diesem Fall werden xsl-Transformationen (oder andere ereignisbasierte Prozessoren) mit einer Vorlage, die mit book: series übereinstimmt, niemals aufgerufen. Wenn Ihr xsl beispielsweise das Buchelement in eine Tabellenzeile (xhtml: tr) umwandelt, erhalten Sie mit dieser Methode möglicherweise die falsche Anzahl von Tabellenzellen (xhtml: td).
  2. Element leer lassen - Dies kann darauf hinweisen, dass die Serie "" oder unbekannt ist oder dass das Buch nicht Teil einer Serie ist. Jede xsl-Transformation (oder ein anderer evernt-basierter Parser), die mit book: series übereinstimmt, wird aufgerufen. Der Wert von current () ist "". Mit dieser Methode erhalten Sie die gleiche Anzahl von xhtml: td-Tags wie mit der nächsten beschriebenen.
  3. Verwenden von xsi: nil = "true" - Dies bedeutet, dass das Element book: series NULL und nicht nur leer ist. Ihre xsl-Transformation (oder ein anderer ereignisbasierter Parser) mit einem Template-Matching-Buch: series wird aufgerufen. Der Wert von current () ist leer (keine leere Zeichenfolge). Der Hauptunterschied zwischen dieser Methode und (2) besteht darin, dass der Schematyp von book: series die leere Zeichenfolge ("") nicht als gültigen Wert zulassen muss. Dies ist für ein Serienelement nicht wirklich sinnvoll, aber für ein Sprachelement, das im Schema als Aufzählungstyp definiert ist, ermöglicht xsi: nil = "true", dass das Element keine Daten enthält. Ein anderes Beispiel wären Elemente vom Typ Dezimal. Wenn Sie möchten, dass sie leer sind, können Sie eine aufgezählte Zeichenfolge, die nur "" und eine Dezimalzahl zulässt, vereinen oder eine nicht zulässige Dezimalstelle verwenden.
KitsuneYMG
quelle
11
Die Verwendung von xsi: nil ist korrekt, aber Sie sollten sicherstellen, dass es sich im richtigen Namespace befindet: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
Es ist tatsächlich xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Beachten Sie das fehlende http: //. Dies ist wichtig, da die Namespace-Zeichenfolge eigentlich nur eine Zeichenfolge für den XML-Parser und keine URL ist.
Burak Arslan
9
Heh, ich glaube das ist noch etwas falsch. Es sollte sein xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Beachten Sie "www.". Siehe w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila
Wie in meiner Antwort angegeben, bin ich mit der Interpretation nicht einverstanden, da es sich nicht um eine Darstellung des Zustands des Elements handelt, sondern um eine Einschränkung der Verwendung des Elements
Oakcool,
2
@ChrisV: Nicht wahr, das xsi:Präfix muss deklariert werden. Ein Namespace-fähiger XML-Parser lehnt Ihr XML-Dokument ab, wenn Sie versuchen, das xsi:Präfix zu verwenden, ohne es zu deklarieren. Die relevante Spezifikation hier ist w3.org/TR/xml-names/#nsc-NSDeclared ("Namespace-Einschränkung: Präfix deklariert"), die besagt, dass die einzigen vordefinierten Präfixe xml:und sind xmlns:. Das XML-Schema baut auf der XML-Namespace-Spezifikation auf, fügt ihr jedoch keine zusätzlichen vordefinierten Präfixe hinzu, da dies tatsächlich die XML-Namespace-Spezifikation verletzen würde.
Simon Kissane
9

Es gibt keine kanonische Antwort, da XML grundsätzlich kein Nullkonzept hat. Ich gehe jedoch davon aus, dass Sie eine XML / Objekt-Zuordnung wünschen (da Objektdiagramme Nullen haben). Die Antwort für Sie lautet also "was auch immer Ihr Werkzeug verwendet". Wenn Sie Handling schreiben, bedeutet das, was Sie bevorzugen. Für Tools, die XML-Schema verwenden, xsi:nilist dies der richtige Weg. Für die meisten Mapper ist das Weglassen eines passenden Elements / Attributs die richtige Vorgehensweise.

StaxMan
quelle
8

Dies hängt davon ab, wie Sie Ihr XML validieren. Wenn Sie die XML-Schemaüberprüfung verwenden, nullwird das xsi:nilAttribut korrekt dargestellt .

[ Quelle ]

Tormod Fjeldskår
quelle
7

Die Dokumentation im w3-Link

http://www.w3.org/TR/REC-xml/#sec-starttags

sagt, dass dies die empfohlenen Formen sind.

<test></test>
<test/>

Das in der anderen Antwort erwähnte Attribut ist ein Validierungsmechanismus und keine Darstellung des Zustands. Weitere Informationen finden Sie unter http://www.w3.org/TR/xmlschema-1/#xsi_nil

XML-Schema: Structures führt einen Mechanismus ein , der signalisiert, dass ein Element als · gültig · akzeptiert werden soll, wenn es trotz eines Inhaltstyps, der keinen leeren Inhalt erfordert oder sogar unbedingt zulässt, keinen Inhalt hat. Ein Element kann ohne Inhalt gültig sein, wenn es das Attribut xsi: nil mit dem Wert true hat. Ein so beschriftetes Element muss leer sein , kann jedoch Attribute enthalten, wenn der entsprechende komplexe Typ dies zulässt.

Um diese Antwort zu verdeutlichen: Inhalt

  <Book>
    <!--Invalid construct since the element attribute xsi:nil="true" signal that the element must be empty-->
    <BuildAttributes HardCover="true" Glued="true" xsi:nil="true">
      <anotherAttribute name="Color">Blue</anotherAttribute>
    </BuildAttributes>
    <Index></Index>
    <pages>
      <page pageNumber="1">Content</page>            
    </pages>
    <!--Missing ISBN number could be confusing and misguiding since its not present-->
  </Book>
</Books>
Oakcool
quelle
7
Das ist die Empfehlung für leere Elemente; Sind Sie der Meinung, dass leer === null? Ich glaube, es gibt einen Unterschied zwischen den beiden, obwohl es oft situativ ist. Wenn Sie die Aussage machen, dass sie gleich sind, würde ich empfehlen, dieses Argument in Ihrer Antwort zu erwähnen.
Rob Hruska
1
Leer ist nicht dasselbe wie null; Wenn dies der Fall wäre, wäre diese Frage zum Stapelüberlauf niemals gestellt worden. Diese Antwort ist falsch. Der Programmierer sollte jedoch bestimmen, ob die Logik, die die XML liest, bereit ist, ein fehlendes Element oder xsi zu behandeln: nil; Wenn nicht, muss möglicherweise eine dieser Formen verwendet werden. Das heißt, es kann erforderlich sein, die Unterscheidung zwischen null / fehlendem Element und einem leeren Element zu verlieren.
ToolmakerSteve
@RobHruska Ja, Sie haben Recht, es ist die Definition eines leeren Elements, aber wenn Sie die W3C-Definition berücksichtigen, auf die KitsuneYMG hinweist, definiert sie, dass das Element null sein muss, und ich glaube, dass diese Darstellung eher die Definition des Elements ist tagge dann die Darstellung seines aktuellen Zustands, daher stimme ich dieser Antwort nicht zu und glaube, dass das Leere die beste Darstellung eines Nullelements ist. Die Idee ist einfach: Um eine gute Struktur aufrechtzuerhalten, müssen alle Elemente dargestellt werden, sonst würden Sie nichts von ihrer Existenz wissen und könnten sie daher falsch darstellen.
Oakcool
4

Sie werden verwendet, xsi:nilwenn Ihre Schemasemantik angibt, dass ein Element einen Standardwert hat und dass der Standardwert verwendet werden sollte, wenn das Element nicht vorhanden ist. Ich muss davon ausgehen, dass es kluge Leute gibt, für die der vorstehende Satz keine selbstverständlich schreckliche Idee ist, aber es klingt für mich nach neun Arten von Schlechtem. Jedes XML-Format, mit dem ich jemals gearbeitet habe, repräsentiert Nullwerte, indem das Element weggelassen wird. (Oder Attribut und viel Glück beim Markieren eines Attributs mit xsi:nil.)

Robert Rossney
quelle
Wenn Sie in einer Dokumentveröffentlichungs-App möchten, dass das Datum auf der Titelseite standardmäßig auf das aktuelle Datum gesetzt wird, wenn das Element keinen Inhalt hat, ist das datevollständige Weglassen des Elements keine große Hilfe, da die App keine Ahnung hat, wo auf der Titelseite Sie möchten das Datum, das angezeigt werden soll. (Wenn das ausgelassene Element nur eine mögliche Position hat, ist dies kein Problem. In realen Dokumentenvokabularen haben fast alle Elemente viele mögliche Positionen.)
CM Sperberg-McQueen
4

Das einfache Weglassen des Attributs oder Elements funktioniert in weniger formalen Daten gut.

Wenn Sie komplexere Informationen benötigen, fügen die GML-Schemas das Attribut nilReason hinzu, z. B.: In GeoSciML :

  • xsi:nil mit dem Wert "true" wird verwendet, um anzuzeigen, dass kein Wert verfügbar ist
  • nilReasonkann verwendet werden, um zusätzliche Informationen für fehlende Werte aufzuzeichnen; Dies kann einer der Standard-GML-Gründe ( missing, inapplicable, withheld, unknown) oder der von vorangestellte Text sein other:oder ein URI-Link zu einer detaillierteren Erklärung sein.

Wenn Sie Daten austauschen, die Rolle, für die XML üblicherweise verwendet wird, können Daten, die an einen Empfänger oder für einen bestimmten Zweck gesendet werden, verdeckte Inhalte aufweisen, die für eine andere Person verfügbar sind, die bezahlt hat oder eine andere Authentifizierung hatte. Es kann sehr wichtig sein, den Grund zu kennen, warum Inhalte fehlten.

Wissenschaftler sind auch besorgt darüber, warum Informationen fehlen. Wenn es beispielsweise aus Qualitätsgründen gelöscht wurde, möchten sie möglicherweise die ursprünglichen fehlerhaften Daten anzeigen.

Andy Dent
quelle
2

In vielen Fällen dient ein Nullwert dazu, einen Datenwert zu liefern, der in einer früheren Version Ihrer Anwendung nicht vorhanden war.

Angenommen, Sie haben eine XML-Datei aus Ihrer Anwendung "ReportMaster" Version 1.

In ReportMaster Version 2 wurden einige weitere Attribute hinzugefügt, die möglicherweise definiert sind oder nicht.

Wenn Sie die Darstellung "Kein Tag bedeutet Null" verwenden, erhalten Sie eine automatische Abwärtskompatibilität zum Lesen Ihrer ReportMaster 1-XML-Datei.

Jeroen Dirks
quelle