Jaki jest prawidłowy sposób reprezentowania pustych elementów XML?

166

Widziałem nullelementy reprezentowane na kilka sposobów:

Element występuje z xsi:nil="true":

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

Element jest obecny, ale reprezentowany jako element pusty (co moim zdaniem jest błędne, ponieważ jest `` pusty '' i nullróżni się semantycznie):

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

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

Elementu w ogóle nie ma w zwracanym znaczniku :

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

Element ma element <null/>potomny (z TStamper poniżej):

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

Czy istnieje poprawny lub kanoniczny sposób przedstawienia takiej nullwartości? Czy istnieją inne sposoby niż powyższe przykłady?

XML dla powyższych przykładów jest sztuczny, więc nie czytaj go zbytnio. :)

Rob Hruska
źródło

Odpowiedzi:

121

xsi: nil to poprawny sposób na przedstawienie wartości takiej, że: Po wywołaniu metody getElementValue () DOM Level 2 zwracana jest wartość NULL. xsi: nil jest również używany do wskazania prawidłowego elementu bez zawartości, nawet jeśli typ zawartości tego elementu zwykle nie zezwala na puste elementy.

Jeśli używany jest pusty tag, getElementValue () zwraca pusty ciąg (""). Jeśli tag zostanie pominięty, nie ma nawet tagu autora. Może to być semantycznie inne niż ustawienie go na „nil” (np. Ustawienie „Series” na zero może oznaczać, że książka nie należy do żadnej serii, podczas gdy pominięcie serii może oznaczać, że seria jest elementem, którego nie można zastosować do bieżącego elementu).

Od: W3C

Schemat XML: Struktury wprowadzają mechanizm sygnalizowania, że ​​element powinien być akceptowany jako · ważny ·, gdy nie ma treści, pomimo tego, że typ zawartości nie wymaga, a nawet koniecznie dopuszcza pustą zawartość. Element może być · prawidłowy · bez treści, jeśli ma atrybut xsi: nil z wartością true. Tak oznaczony element musi być pusty, ale może przenosić atrybuty, jeśli zezwala na to odpowiedni typ złożony.

Wyjaśnienie:
jeśli masz element xml książki, a jednym z elementów podrzędnych jest book: series, masz kilka opcji podczas wypełniania go:

  1. Całkowite usunięcie elementu - można to zrobić, jeśli chcesz wskazać, że seria nie ma zastosowania do tej książki lub że książka nie należy do serii. W tym przypadku transformacje xsl (lub inne procesory oparte na zdarzeniach), które mają szablon pasujący do book: series, nigdy nie zostaną wywołane. Na przykład, jeśli twój xsl zamienia element książki w wiersz tabeli (xhtml: tr), możesz uzyskać nieprawidłową liczbę komórek tabeli (xhtml: td) przy użyciu tej metody.
  2. Pozostawienie elementu pustego - może to oznaczać, że seria jest „” lub jest nieznana lub że książka nie jest częścią serii. Dowolna transformacja xsl (lub inny parser oparty na evernt), która pasuje do book: series, zostanie wywołana. Wartość current () będzie wynosić „”. Otrzymasz taką samą liczbę tagów xhtml: td używając tej metody, jak w przypadku następnego opisanego.
  3. Używanie xsi: nil = "true" - oznacza to, że element book: series ma wartość NULL, a nie tylko jest pusty. Twoja transformacja xsl (lub inny parser oparty na zdarzeniach), który ma szablon pasujący do book: series, zostanie nazwany. Wartość current () będzie pusta (nie pusty ciąg). Główna różnica między tą metodą a (2) polega na tym, że typ schematu book: series nie musi dopuszczać pustego ciągu („”) jako prawidłowej wartości. Nie ma to sensu w przypadku elementu serii, ale w przypadku elementu języka zdefiniowanego jako typ wyliczeniowy w schemacie xsi: nil = "true" pozwala, aby element nie miał danych. Innym przykładem mogą być elementy typu decimal. Jeśli chcesz, aby były puste, możesz połączyć wyliczany ciąg, który dopuszcza tylko „” i liczbę dziesiętną, lub użyć liczby dziesiętnej, która jest zerowa.
KitsuneYMG
źródło
11
Użycie xsi: nil jest poprawne, ale należy się upewnić, że znajduje się on w odpowiedniej przestrzeni nazw: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
Właściwie to xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Zwróć uwagę na brakujący http: //. Jest to ważne, ponieważ ciąg przestrzeni nazw jest w rzeczywistości tylko ciągiem do parsera xml, a nie identyfikatorem URI.
Burak Arslan
9
Heh, uważam, że to nadal jest trochę błędne. Tak powinno być xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Uwaga „www.”. Zobacz w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila,
Jak stwierdzono w mojej odpowiedzi, nie zgadzam się z interpretacją, ponieważ nie jest ona reprezentacją stanu elementu, ale ograniczeniem użycia elementu
Oakcool,
2
@ChrisV: nieprawda, xsi:prefiks musi zostać zadeklarowany. Analizator składni XML uwzględniający przestrzeń nazw odrzuci dokument XML, jeśli spróbujesz użyć xsi:przedrostka bez deklarowania go. Odpowiednia specyfikacja to w3.org/TR/xml-names/#nsc-NSDeclared ("Ograniczenie przestrzeni nazw: zadeklarowany prefiks"), która mówi, że jedynymi predefiniowanymi przedrostkami są xml:i xmlns:. Schemat XML opiera się na specyfikacji przestrzeni nazw XML, ale nie dodaje do niej żadnych dodatkowych predefiniowanych przedrostków, ponieważ w rzeczywistości naruszyłoby to specyfikację przestrzeni nazw XML.
Simon Kissane,
9

Nie ma kanonicznej odpowiedzi, ponieważ XML zasadniczo nie ma pojęcia zerowego. Ale zakładam, że chcesz mapować Xml / Object (ponieważ wykresy obiektów mają wartości null); więc odpowiedzią dla ciebie jest „cokolwiek używa twoje narzędzie”. Jeśli piszesz obsługę, oznacza to, co wolisz. W przypadku narzędzi korzystających ze schematu XML xsi:niljest do zrobienia. W przypadku większości maperów sposobem na zrobienie tego jest pominięcie pasującego elementu / atrybutu.

StaxMan
źródło
8

To zależy od tego, jak zweryfikujesz swój XML. Jeśli używasz sprawdzania poprawności schematu XML, prawidłowym sposobem przedstawiania nullwartości jest xsi:nilatrybut.

[ Źródło ]

Tormod Fjeldskår
źródło
7

Dokumentacja w linku w3

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

mówi, że to są zalecane formy.

<test></test>
<test/>

Atrybut wymieniony w drugiej odpowiedzi to mechanizm walidacji, a nie reprezentacja stanu. Zapoznaj się z http://www.w3.org/TR/xmlschema-1/#xsi_nil

Schemat XML: Struktury wprowadzają mechanizm sygnalizowania, że ​​element powinien być akceptowany jako · ważny ·, gdy nie ma treści pomimo typu zawartości, który nie wymaga lub nawet koniecznie dopuszcza pustą zawartość. Element może być · prawidłowy · bez treści, jeśli ma atrybut xsi: nil z wartością true. Tak oznaczony element musi być pusty , ale może przenosić atrybuty, jeśli zezwala na to odpowiedni typ złożony.

Aby wyjaśnić tę odpowiedź: Treść

  <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
źródło
7
To jest zalecenie dla pustych elementów; czy uważasz, że puste === null? Uważam, że istnieje różnica między nimi, chociaż często jest to sytuacja sytuacyjna. Jeśli twierdzisz, że są takie same, radzę wspomnieć o tym argumencie w swojej odpowiedzi.
Rob Hruska
1
Puste to nie to samo, co null; gdyby tak było, to pytanie o przepełnienie stosu nigdy nie zostałoby zadane. Ta odpowiedź jest błędna. Jednak programista powinien określić, czy logika, która będzie czytać xml jest przygotowana do obsługi brakującego elementu, czy też xsi: nil; jeśli nie, może być konieczne użycie jednego z tych formularzy; oznacza to, że może być konieczna utrata rozróżnienia między pustym / brakującym elementem a pustym elementem.
ToolmakerSteve
@RobHruska tak, masz rację, to jest definicja pustego elementu, ale jeśli weźmie się pod uwagę definicję W3C wskazaną przez KitsuneYMG, to określa, że ​​element musi być pusty i uważam, że ta reprezentacja jest bardziej definicją elementu tag to reprezentacja jego aktualnego stanu, więc nie zgadzam się z tą odpowiedzią i uważam, że puste jest najlepszą reprezentacją elementu zerowego. Pomysł jest prosty, aby zachować dobrą strukturę, wszystkie elementy muszą być reprezentowane, w przeciwnym razie nie wiedziałbyś o jego istnieniu i dlatego mógłbyś go błędnie przedstawić.
Oakcool
4

Użyć xsi:nil, gdy semantyka schematu wynika, że element ma wartość domyślną, a wartość domyślna powinny być stosowane, jeśli element nie jest obecny. Muszę założyć, że są mądrzy ludzie, dla których poprzednie zdanie nie jest ewidentnie okropnym pomysłem, ale dla mnie brzmi to jak dziewięć rodzajów złego. Każdy format XML, z jakim kiedykolwiek pracowałem, reprezentuje wartości null, pomijając element. (Lub atrybut i powodzenia w oznaczaniu atrybutu za pomocą xsi:nil.)

Robert Rossney
źródło
Jeśli w aplikacji do publikowania dokumentów chcesz, aby data na stronie tytułowej była domyślną datą bieżącą, jeśli element nie zawiera treści, datecałkowite pominięcie elementu nie jest zbyt pomocne, ponieważ aplikacja nie będzie miała pojęcia, gdzie na stronie tytułowej chcesz data pojawienia się. (Jeśli pominięty element ma tylko jedną możliwą lokalizację, nie stanowi to problemu; w prawdziwych słownikach dokumentów prawie wszystkie elementy mają wiele możliwych lokalizacji.)
CM Sperberg-McQueen
4

Zwykłe pominięcie atrybutu lub elementu działa dobrze w mniej formalnych danych.

Jeśli potrzebujesz bardziej wyrafinowanych informacji, schematy GML dodają atrybut nilReason, np .: w GeoSciML :

  • xsi:nil z wartością „prawda” służy do wskazania, że ​​żadna wartość nie jest dostępna
  • nilReasonmożna wykorzystać do zapisania dodatkowych informacji o brakujących wartościach; może to być jeden ze standardowych powodów GML ( missing, inapplicable, withheld, unknown) lub tekst poprzedzony other:lub może być odsyłaczem URI do bardziej szczegółowego wyjaśnienia.

Podczas wymiany danych, w przypadku roli, do której powszechnie używany jest XML, dane wysyłane do jednego odbiorcy lub w określonym celu mogą mieć zasłoniętą zawartość, która byłaby dostępna dla kogoś innego, kto zapłacił lub miał inne uwierzytelnienie. Znajomość przyczyny braku treści może być bardzo ważna.

Naukowcy martwią się również, dlaczego brakuje informacji. Na przykład, jeśli został usunięty ze względu na jakość, mogą chcieć zobaczyć oryginalne złe dane.

Andy Dent
źródło
2

W wielu przypadkach wartość Null służy do obsługi wartości danych, których nie było w poprzedniej wersji aplikacji.

Powiedzmy, że masz plik xml z aplikacji „ReportMaster” w wersji 1.

Teraz w ReportMaster w wersji 2 dodano więcej atrybutów, które mogą być zdefiniowane lub nie.

Jeśli użyjesz reprezentacji „brak tagu oznacza zero”, uzyskasz automatyczną wsteczną zgodność odczytu pliku XML ReportMaster 1.

Jeroen Dirks
źródło