Apa cara yang benar untuk mewakili elemen XML nol?

166

Saya telah melihat nullelemen diwakili dalam beberapa cara:

Elemen hadir dengan xsi:nil="true":

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

Elemen itu ada, tetapi direpresentasikan sebagai elemen kosong (yang saya yakini salah karena 'kosong' dan nullsecara semantik berbeda):

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

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

Elemen tidak ada sama sekali di markup yang dikembalikan :

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

Elemen ini memiliki elemen <null/>anak (dari TStamper di bawah):

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

Apakah ada cara yang benar atau kanonik untuk mewakili nullnilai seperti itu ? Apakah ada cara tambahan selain contoh di atas?

XML untuk contoh di atas dibuat, jadi jangan membaca terlalu jauh. :)

Rob Hruska
sumber

Jawaban:

121

xsi: nil adalah cara yang benar untuk mewakili nilai sehingga: Ketika panggilan DOM Level 2 getElementValue () dikeluarkan, nilai NULL dikembalikan. xsi: nil juga digunakan untuk menunjukkan elemen yang valid tanpa konten walaupun tipe elemen itu biasanya tidak mengijinkan elemen kosong.

Jika tag kosong digunakan, getElementValue () mengembalikan string kosong ("") Jika tag dihilangkan, maka tidak ada tag penulis bahkan ada. Ini mungkin secara semantik berbeda dari menetapkannya ke 'nihil' (Mis. Mengatur "Seri" ke nihil mungkin bahwa buku tersebut tidak termasuk seri, sedangkan menghilangkan seri dapat berarti bahwa seri adalah elemen yang tidak dapat diterapkan untuk elemen saat ini.)

Dari: W3C

Skema XML: Struktur memperkenalkan mekanisme pensinyalan bahwa suatu elemen harus diterima sebagai · valid · ketika tidak memiliki konten terlepas dari jenis konten yang tidak memerlukan atau bahkan perlu mengizinkan konten kosong. Suatu elemen dapat · valid · tanpa konten jika memiliki atribut xsi: nil dengan nilai true. Elemen yang diberi label harus kosong, tetapi dapat membawa atribut jika diizinkan oleh tipe kompleks yang sesuai.

Klarifikasi:
Jika Anda memiliki elemen buku xml dan salah satu elemen turunannya adalah buku: seri, Anda memiliki beberapa opsi saat mengisinya:

  1. Menghapus elemen seluruhnya - Ini dapat dilakukan ketika Anda ingin menunjukkan bahwa seri tidak berlaku untuk buku ini atau buku itu bukan bagian dari seri. Dalam hal ini xsl mentransformasikan (atau pemroses berbasis peristiwa lainnya) yang memiliki templat yang cocok dengan buku: seri tidak akan pernah dipanggil. Misalnya, jika xsl Anda mengubah elemen buku menjadi baris tabel (xhtml: tr) Anda mungkin mendapatkan jumlah sel tabel yang salah (xhtml: td) menggunakan metode ini.
  2. Membiarkan elemen kosong - Ini bisa menunjukkan bahwa rangkaian "", atau tidak diketahui, atau bahwa buku itu bukan bagian dari rangkaian. Setiap transformasi xsl (atau parser berbasiskan lainnya) yang cocok dengan buku: seri akan dipanggil. Nilai saat ini () akan menjadi "". Anda akan mendapatkan jumlah tag xhtml: td yang sama menggunakan metode ini seperti yang dijelaskan berikutnya.
  3. Menggunakan xsi: nil = "true" - Ini menandakan bahwa elemen book: series NULL, tidak hanya kosong. Transformasi xsl Anda (atau parser berbasis peristiwa lainnya) yang memiliki buku pencocokan templat: seri akan dipanggil. Nilai current () akan kosong (bukan string kosong). Perbedaan utama antara metode ini dan (2) adalah bahwa jenis skema buku: seri tidak perlu mengizinkan string kosong ("") sebagai nilai yang valid. Ini tidak masuk akal untuk elemen seri, tetapi untuk elemen bahasa yang didefinisikan sebagai tipe enumerasi dalam skema, xsi: nil = "true" memungkinkan elemen tidak memiliki data. Contoh lain adalah elemen dari tipe desimal. Jika Anda ingin mereka kosong, Anda dapat menyatukan string yang dihitung yang hanya memungkinkan "" dan desimal, atau menggunakan desimal yang tidak dapat diisi.
KitsuneYMG
sumber
11
Menggunakan xsi: nil benar, tetapi Anda harus memastikan bahwa itu berada dalam namespace yang tepat: xmlns: xsi = " w3.org/2001/XMLSchema-instance "
STW
Sebenarnya xmlns:xsi="http://w3.org/2001/XMLSchema-instance". Perhatikan http yang hilang: //. Ini penting karena string namespace sebenarnya hanya string ke parser xml dan bukan uri.
Burak Arslan
9
Heh, saya yakin itu masih sedikit salah. Seharusnya begitu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance". Catatan "www.". Lihat w3.org/TR/xmlschema-1/#no-xsi
Janne Mattila
Seperti yang dinyatakan pada jawaban saya, saya tidak setuju dengan interpretasi karena itu bukan representasi dari keadaan elemen, tetapi kendala pada penggunaan elemen
Oakcool
2
@ ChrisV: Tidak benar, xsi:awalan harus dideklarasikan. Pengurai XML namespace-aware akan menolak dokumen XML Anda jika Anda mencoba menggunakan xsi:awalan tanpa mendeklarasikannya. Spesifikasi yang relevan di sini adalah w3.org/TR/xml-names/#nsc-NSDeclared ("Namespace constraint: Prefix Declared") yang mengatakan bahwa satu-satunya awalan yang telah ditentukan adalah xml:dan xmlns:. Skema XML dibuat di atas spesifikasi ruang nama XML tetapi tidak menambahkan awalan standar yang telah ditentukan sebelumnya, karena melakukan itu akan benar-benar melanggar spesifikasi ruang nama XML.
Simon Kissane
9

Tidak ada jawaban kanonik, karena XML pada dasarnya tidak memiliki konsep nol. Tapi saya berasumsi Anda ingin pemetaan Xml / Obyek (karena grafik objek memiliki nol); jadi jawaban untuk Anda adalah "apa pun yang menggunakan alat Anda". Jika Anda menulis penanganan, itu berarti apa pun yang Anda inginkan. Untuk alat yang menggunakan Skema XML, xsi:niladalah caranya. Untuk sebagian besar pemetaan, menghilangkan elemen / atribut yang cocok adalah cara untuk melakukannya.

StaxMan
sumber
8

Itu tergantung pada bagaimana Anda memvalidasi XML Anda. Jika Anda menggunakan validasi Skema XML, cara yang benar untuk merepresentasikan nullnilai adalah dengan xsi:nilatribut.

[ Sumber ]

Tormod Fjeldskår
sumber
7

Dokumentasi di tautan w3

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

mengatakan bahwa ini adalah bentuk yang direkomendasikan.

<test></test>
<test/>

Atribut yang disebutkan dalam jawaban lain adalah mekanisme validasi dan bukan representasi negara. Silakan merujuk ke http://www.w3.org/TR/xmlschema-1/#xsi_nil

Skema XML: Struktur memperkenalkan mekanisme pensinyalan bahwa suatu elemen harus diterima sebagai · valid · ketika tidak memiliki konten terlepas dari jenis konten yang tidak memerlukan atau bahkan perlu mengizinkan konten kosong. Suatu elemen dapat · valid · tanpa konten jika memiliki atribut xsi: nil dengan nilai true. Elemen yang diberi label harus kosong , tetapi dapat membawa atribut jika diizinkan oleh tipe kompleks yang sesuai.

Untuk memperjelas jawaban ini: Konten

  <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
sumber
7
Itulah rekomendasi untuk elemen kosong ; apakah Anda berpendapat bahwa === nol kosong? Saya percaya ada perbedaan di antara keduanya, meskipun sering situasional. Jika Anda membuat pernyataan bahwa mereka sama, saya sarankan menyebutkan argumen itu dalam jawaban Anda.
Rob Hruska
1
Kosong tidak sama dengan nol; jika ya, pertanyaan stackoverflow ini tidak akan pernah ditanyakan. Jawaban ini salah. Namun, programmer harus menentukan apakah logika yang akan membaca xml disiapkan untuk menangani elemen yang hilang atau xsi: nil; jika tidak, mungkin perlu menggunakan salah satu dari formulir ini; yaitu, mungkin perlu kehilangan perbedaan antara elemen null / missing dan elemen kosong.
ToolmakerSteve
@RobHruska ya, Anda benar, itu adalah definisi elemen kosong, tetapi jika mempertimbangkan definisi W3C yang ditunjukkan oleh KitsuneYMG, itu mendefinisikan bahwa elemen tersebut harus nol dan saya percaya bahwa representasi itu lebih merupakan definisi dari tandai representasi negara saat ini, jadi saya tidak setuju dengan jawaban itu, dan yakin bahwa yang kosong adalah representasi terbaik dari elemen nol. Idenya sederhana, untuk mempertahankan struktur yang baik, Anda perlu semua elemen diwakili jika tidak Anda tidak akan tahu keberadaannya, dan karena itu bisa salah mengartikannya.
Oakcool
4

Anda menggunakan xsi:nilketika semantik skema Anda menunjukkan bahwa suatu elemen memiliki nilai default, dan bahwa nilai default harus digunakan jika elemen tersebut tidak ada. Saya harus berasumsi bahwa ada orang-orang pintar yang kepadanya kalimat sebelumnya bukanlah ide yang jelas-jelas mengerikan, tetapi kedengarannya seperti sembilan jenis buruk bagi saya. Setiap format XML yang pernah saya kerjakan mewakili nilai nol dengan menghilangkan elemen. (Atau atribut, dan semoga sukses menandai atribut dengan xsi:nil.)

Robert Rossney
sumber
Jika dalam aplikasi publikasi dokumen Anda ingin tanggal pada halaman judul secara default ke tanggal saat ini jika elemen tidak memiliki konten, menghilangkan dateelemen sepenuhnya tidak banyak membantu, karena aplikasi tidak akan tahu di mana pada halaman judul yang Anda inginkan tanggal yang akan muncul. (Jika elemen yang dihilangkan hanya memiliki satu lokasi yang memungkinkan, ini bukan masalah; dalam kosakata dokumen nyata hampir semua elemen memiliki banyak lokasi yang memungkinkan.)
CM Sperberg-McQueen
4

Menghilangkan atribut atau elemen berfungsi dengan baik dalam data yang kurang formal.

Jika Anda memerlukan informasi yang lebih canggih, skema GML menambahkan atribut nilReason, misalnya: di GeoSciML :

  • xsi:nil dengan nilai "true" digunakan untuk menunjukkan bahwa tidak ada nilai yang tersedia
  • nilReasondapat digunakan untuk mencatat informasi tambahan untuk nilai yang hilang; ini mungkin salah satu alasan GML standar ( missing, inapplicable, withheld, unknown), atau teks yang diawali dengan other:, atau mungkin tautan URI ke penjelasan yang lebih terperinci.

Saat Anda bertukar data, peran yang biasa digunakan XML, data yang dikirim ke satu penerima atau untuk tujuan tertentu mungkin memiliki konten yang dikaburkan yang akan tersedia untuk orang lain yang membayar atau memiliki otentikasi berbeda. Mengetahui alasan mengapa konten hilang bisa sangat penting.

Para ilmuwan juga prihatin dengan mengapa informasi hilang. Misalnya, jika dijatuhkan karena alasan kualitas, mereka mungkin ingin melihat data buruk asli.

Andy Dent
sumber
2

Dalam banyak kasus tujuan dari nilai Null adalah untuk melayani nilai data yang tidak ada dalam versi aplikasi Anda sebelumnya.

Jadi, katakan Anda memiliki file xml dari aplikasi Anda "ReportMaster" versi 1.

Sekarang dalam ReportMaster versi 2, beberapa atribut telah ditambahkan yang mungkin atau tidak didefinisikan.

Jika Anda menggunakan representasi 'tanpa tag berarti nol', Anda mendapatkan kompatibilitas mundur otomatis untuk membaca file ReportMaster 1 xml Anda.

Jeroen Dirks
sumber