Атрибут XML проти елемента XML


253

На роботі нас просять створити XML-файли для передачі даних в іншу офлайн-програму, яка потім створить другий XML-файл для передачі назад, щоб оновити деякі наші дані. Під час процесу ми обговорювали з командою іншої програми про структуру файлу XML.

Зразок, який я придумав, по суті є чимось на кшталт:

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

Інша команда сказала, що це не є галузевим стандартом і що атрибути слід використовувати лише для метаданих. Вони запропонували:

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

Причиною, яку я запропонував першою, є те, що розмір створеного файлу значно менший. Під час передачі буде у файлі приблизно 80000 елементів, які будуть у файлі. Їх пропозиція насправді виявляється втричі більшою за ту, яку я запропонував. Я шукав таємничий "галузевий стандарт", про який згадувалося, але найбільш близьким, що я міг знайти, було те, що атрибути XML слід використовувати лише для метаданих, але сказав, що дискусія стосувалася того, що насправді є метаданими.

Після довгохвильового пояснення (вибачте) як ви визначаєте, що таке метадані, і при проектуванні структури документа XML як слід вирішити, коли використовувати атрибут чи елемент?


4
Я знайшов цей дійсно хороший ресурс: ibm.com/developerworks/xml/library/x-eleatt.html
Laurens Holst

5
+1 за "... дебати про те, що насправді були метаданими".
Затримано

Зверніть увагу на малі імена тегів з дефісами: stackoverflow.com/questions/1074447/…
Бен

Відповіді:


145

Я використовую це правило:

  1. Атрибут - це щось самодостатнє, тобто колір, ідентифікатор, ім'я.
  2. Елемент - це те, що має або може мати власні атрибути або містити інші елементи.

Тож ваша близька. Я зробив би щось на кшталт:

EDIT : оновлено оригінальний приклад на основі наведених нижче відгуків.

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

22
Я прочитав деякі відповіді, і те, що було недостатньо підкреслено, мій досвід, це те, що якщо ви отримаєте дані в "атрибуті" і раптом має документ> або <ви, XML документ зламається, я думаю, що є п'ять символів ascii (>, <, &,?, ") це вб'є це. Якщо цей спеціальний символ був у Елементі, ви можете просто додати деякі теги CDATA навколо цих даних. Я б сказав, використовуйте атрибути лише тоді, коли ви на 100% знаєте, які значення будете ставити там, наприклад, ціле число або дата, можливо, все, що генерується на комп’ютері. Якщо штрихкод був створений людиною, то це не повинно бути атрибутом.
Джон Баллінгер,

39
Дійсно спізнюється з учасником, але спеціальний аргумент ASCII char невірний - саме для цього потрібні атрибути та текстові дані.
Міхейтан

2
@donroby - Вибачте, це була б моя помилка в спілкуванні. Під втечею я маю на увазі кодування XML. '<' = & lt; тощо. Мені здається дивним вирішувати між атрибутом чи елементом на основі символів, які складають зміст замість значення вмісту.
Міхейтан

3
@donroby: це неправильно. Заміна текст &lt;IS &#60;, який є посиланням характеру, не є посиланням на об'єкт. &lt;в атрибутах добре. Дивіться: w3.org/TR/REC-xml/#sec-predefined-ent
porges

14
@John: якщо це проблема, то у вашій інструментальній ланцюжку є щось, що не створює дійсний XML. Я не думаю, що це причина вибору між атрибутами чи елементами. (Крім того, ви не можете "просто додати теги CDATA" навколо вводу користувача, тому що він може містити ]]>!)
porges

48

Деякі проблеми з атрибутами:

  • атрибути не можуть містити декілька значень (дочірні елементи можуть)
  • атрибути не легко розширюються (для майбутніх змін)
  • атрибути не можуть описати структури (дочірні елементи можуть)
  • атрибути важче маніпулювати програмним кодом
  • значення атрибутів непросто перевірити на DTD

Якщо ви використовуєте атрибути як контейнери для даних, ви отримуєте документи, які важко читати та підтримувати. Спробуйте використовувати елементи для опису даних. Використовуйте атрибути лише для надання інформації, яка не стосується даних.

Не закінчуйте так (це не спосіб використання XML):

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

Джерело: http://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp


2
Перший пункт невірний, див.: W3.org/TR/xmlschema-2/#derivation-by-list
porges

6
Я б сказав, що перший пункт є правильним і listє частковим вирішенням цієї проблеми. Не може бути декількох атрибутів з одним іменем. У listатрибута все ще є лише одне значення, яке є розділеним пробілом списком деяких типів даних. Символи розділення фіксуються, тому ви не можете мати кілька значень, якщо одне значення шуканого типу даних може містити пробіл. Це виключає шанси на наявність, наприклад, декількох адрес в одному атрибуті "address".
jasso

7
'атрибути важче маніпулювати програмним кодом' - Не можу погодитися з цим. Насправді я виявив протилежне. Різниці недостатньо, щоб дійсно заявити в будь-якому випадку.
Павло Олександр

4
Я також додаю, що перевірка DTD вже не є актуальною для XML-Schema, Schematron та Relax та ін. ін. все це забезпечує набагато більш потужний і в деяких випадках інтуїтивніший спосіб перевірки XML-документів. Крім того, W3Schools - це дійсно погана довідка для будь-чого

37

"XML" означає "eXtensible Markup Language". Мова розмітки означає, що дані - це текст, позначений метаданими про структуру чи форматування.

XHTML - приклад використання XML так, як було призначено:

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

Тут чітке розмежування елементів та атрибутів. Текстові елементи відображаються в браузері, і атрибути інструкції про те, як їх відобразити (хоча є кілька тегів , які не працюють таким чином).

Плутанина виникає, коли XML використовується не як мова розмітки, а як мова серіалізації даних , в якій відмінність "дані" від "метаданих" є більш невиразним. Отже вибір між елементами та атрибутами більш-менш довільний за винятком речей, які не можуть бути представлені атрибутами (див. Відповідь feenster).


32

Елемент XML та атрибут XML

XML - все про узгодження. Спочатку відкладіть будь-які існуючі XML-схеми або встановлені конвенції у вашій спільноті чи галузі.

Якщо ви справді в змозі визначити свою схему з нуля, ось декілька загальних міркувань, які повинні повідомити елемент vs атрибут рішення :

<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

Це може залежати від вашого використання. XML, який використовується для представлення структурованих даних, згенерованих з бази даних, може добре працювати з кінцевими значеннями поля, розміщеними як атрибути.

Однак XML, який використовується як транспорт повідомлення, часто краще використовувати більше елементів.

Наприклад, скажімо, що у нас був цей XML, як було запропоновано у відповіді:

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

Тепер ми хочемо надіслати елемент ITEM на пристрій для друку штрих-коду, проте існує вибір типів кодування. Як ми представляємо потрібний тип кодування? Раптом ми розуміємо, дещо запізніло, що штрих-код не був єдиним автоматичним значенням, а навпаки, він може бути кваліфікований з необхідним кодуванням при друкуванні.

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

Справа полягає в тому, що якщо ви не будуєте якийсь XSD або DTD разом з простором імен, щоб виправити структуру в камені, вам, можливо, найкраще служити, залишаючи параметри відкритими.

IMO XML є найбільш корисним, коли його можна згинати, не порушуючи існуючого коду, використовуючи його.


Хороший пункт про "штрих-код", я поспішив на свій приклад і, безумовно, розбив би це на свій власний елемент. Також хороший момент на XSD / DTD.
Чак

10

Я використовую наступні вказівки в моєму дизайні схеми щодо атрибутів проти елементів:

  • Використовуйте елементи для тривалого запуску тексту (як правило, рядкових або normalizedString типів)
  • Не використовуйте атрибут, якщо для елемента є групування двох значень (наприклад, eventStartDate та eventEndDate). У попередньому прикладі повинен бути новий елемент для "події", який може містити атрибути startDate та endDate.
  • Бізнес-дата, дата-час та цифри (наприклад, рахунки, сума та ставка) повинні бути елементами.
  • Елементи атрибутів мають бути нечасними елементами часу, такими як останній раз оновлений, закінчується.
  • Атрибути повинні бути атрибутами, що не стосуються бізнесу, наприклад хеш-кодами та індексами. * Використовуйте елементи, якщо тип буде складним.
  • Використовуйте атрибути, якщо значення є простим типом і не повторюється.
  • xml: id та xml: lang повинні бути атрибутами, що посилаються на схему XML
  • Віддавайте перевагу атрибутам, коли це технічно можливо.

Перевагою атрибутів є те, що він забезпечує наступне:

  • унікальний (атрибут не може з’являтися кілька разів)
  • порядок не має значення
  • вищевказані властивості успадковуються (це те, що модель вмісту "все" не підтримує поточну мову схеми)
  • бонус полягає в тому, що вони менш багатослівні та використовують меншу пропускну здатність, але це насправді не є причиною віддавати перевагу атрибутам над елементами.

Я додав, коли це технічно можливо, тому що бувають випадки, коли використання атрибутів неможливе. Наприклад, вибір атрибутів. Наприклад, використання (startDate та endDate) xor (startTS та endTS) неможливо з поточною мовою схеми

Якщо схема XML почне дозволяти обмежувати або розширювати модель вмісту "всі", я, мабуть, відмовиться від неї


8

Коли ви сумніваєтесь, KISS - навіщо змішувати атрибути та елементи, коли у вас немає чіткої причини використовувати атрибути. Якщо пізніше ви вирішите визначити XSD, це також стане чистішим. Тоді, якщо ви навіть пізніше вирішите генерувати структуру класу зі свого XSD, це буде також простішим.


8

Універсальної відповіді на це питання немає (я активно брав участь у створенні специфікації W3C). XML можна використовувати для багатьох цілей - текстові документи, дані та декларативний код - три найпоширеніші. Я також дуже багато його використовую як модель даних. Існують аспекти цих додатків, коли атрибути є більш поширеними та інші, де дочірні елементи більш природні. Також є особливості різних інструментів, які полегшують або складніше їх використовувати.

XHTML - це одна область, де атрибути мають природне використання (наприклад, у class = 'foo'). Атрибути не мають порядку, і це може полегшити розробку інструментів для деяких людей. Атрибути OTOH важче набрати без схеми. Я також знаходжу атрибути, розміщені з іменами (foo: bar = "zork"), часто важче керувати в різних наборах інструментів. Але подивіться деякі мови W3C, щоб побачити суміш, яка є загальною. SVG, XSLT, XSD, MathML - деякі приклади добре відомих мов і всі мають багатий набір атрибутів та елементів. Деякі мови навіть дозволяють зробити це не одним способом, наприклад

<foo title="bar"/>;

або

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

Зауважте, що це НЕ еквівалентно синтаксично і потребують явної підтримки в інструментах обробки)

Моя порада полягає в тому, щоб ознайомитись із загальною практикою в області, найближчій до вашої заявки, а також розглянути, які набори інструментів ви хочете застосувати.

Нарешті переконайтесь, що ви відрізняєте простори імен від атрибутів. Деякі системи XML (наприклад, Linq) представляють простори імен як атрибути в API. ІМО це некрасиво і потенційно заплутано.


6

Інші розповіли, як відрізняти атрибути від елементів, але з більш загальної точки зору, вкладаючи все в атрибути, оскільки це робить отриманий XML меншим - це неправильно.

XML не розроблений таким чином, щоб бути компактним, але бути портативним та зрозумілим для людини. Якщо ви хочете зменшити розмір даних під час транзиту, тоді використовуйте щось інше (наприклад , буфери протоколів google ).


Менший XML-текст легше читати лише тому, що він менший!
Нашев

5

питання про мільйон доларів!

по-перше, зараз не надто переживайте про продуктивність. Ви будете вражені тим, як швидко оптимізований аналізатор xml прорве ваш xml. Що ще важливіше, який ваш дизайн на майбутнє: у міру розвитку XML, як ви будете підтримувати нещільне з'єднання та сумісність?

конкретніше, ви можете зробити змістову модель елемента складнішою, але складніше розширити атрибут.


5

Обидва способи зберігання властивостей об'єкта цілком справедливі. Вам слід відійти від прагматичних міркувань. Спробуйте відповісти на таке запитання:

  1. Яке представлення призводить до швидшого аналізу даних \ генерації?

  2. Яке представлення призводить до швидшої передачі даних?

  3. Чи має значення читабельність?

    ...


5

Використовуйте елементи для даних та атрибутів для метаданих (дані про дані елемента).

Якщо елемент відображається як предикат у вибраних рядках, ви маєте хороший знак, що він повинен бути атрибутом. Так само, якщо атрибут ніколи не використовується як предикат, то, можливо, це не корисні метадані.

Пам'ятайте, що XML повинен бути машиночитаним, не читабельним для людей, а для великих документів XML стискається дуже добре.


4

Це в будь-якому випадку суперечить, але ваші колеги мають рацію в тому сенсі, що XML слід використовувати для "розмітки" або метаданих навколо фактичних даних. Зі свого боку, ви маєте рацію в тому, що іноді важко визначити, де знаходиться лінія між метаданими та даними при моделюванні вашого домену в XML. На практиці я роблю вигляд, що що-небудь у розмітці приховано, і тільки дані поза розміткою читаються. Чи має документ у цьому певний сенс?

XML, як відомо, є об'ємним. Для транспортування та зберігання настійно рекомендується стиснення, якщо ви можете дозволити собі потужність обробки. XML здавлює добре, іноді феноменально добре, через свою повторюваність. У мене великі файли стискаються до менш ніж 5% від їх початкового розміру.

Ще одним моментом для посилення вашої позиції є те, що в той час, як інша команда сперечається щодо стилю (в тому, що більшість інструментів XML обробляє документ з усіма атрибутами так само легко, як і документ із усіма документами PCDATA), ви сперечаєтесь із практичністю. Хоча стиль не можна повністю ігнорувати, технічні достоїнства повинні мати більшу вагу.


4

Це багато в чому питання переваги. Я використовую елементи для групування та атрибутів для даних, де це можливо, оскільки я вважаю це більш компактним, ніж альтернативу.

Наприклад, я віддаю перевагу .....

<?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>

...Замість....

<?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>

Однак якщо у мене є дані, які не представляються легко, скажімо, 20-30 символів або містять багато лапок або інших символів, які потребують втечі, то я б сказав, що настав час розбити елементи ... можливо, з блоками 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
Боюся, це неправильно. Боюся, ви повинні дотримуватися вказівок W3C: w3schools.com/DTD/dtd_el_vs_attr.asp - XML ​​не повинен формуватися на читанні чи робити його "компактним" - а використовувати елементи чи атрибути правильно для цієї мети для чого вони були розроблені.
Відар

24
Перепрошую, але це вводить в оману. Сторінка W3schools - це не правило W3C. Рекомендація W3C XML (в якій я був учасником) дозволяє використовувати елементи та атрибути відповідно до потреб та стилів користувачів.
peter.murray.rust

4

Як щодо використання нашої важко заробленої інтуїції орієнтації на об'єкт? Зазвичай я вважаю, що прямо вперед подумати, що є об'єктом, а яке - атрибутом об'єкта чи про який об'єкт йдеться.

Що б інтуїтивно не мало сенсу, оскільки об'єкти повинні входити в елементи. Його атрибути (або властивості) будуть атрибутами для цих елементів у xml або дочірньому елементі з атрибутом.

Я думаю, що для більш простих випадків, наприклад, у прикладі аналогії орієнтації на об'єкт, добре працює, щоб зрозуміти, що є елементом, а який - атрибутом елемента.


2

Кілька виправлень поганої інформації:

@John Ballinger: Атрибути можуть містити будь-які дані символів. <> & "'потрібно вийти відповідно до & amp; & & quot; відповідно. Якщо ви використовуєте бібліотеку XML, вона подбає про це за вас.

Пекло, атрибут може містити бінарні дані, такі як зображення, якщо ви дуже хочете, просто базуючи його на коді6464 і перетворюючи на нього дані: URL.

@feenster: Атрибути можуть містити кілька елементів, розділених пробілом, у випадку IDS або NAMES, які включатимуть числа. Нітпікі, але це може призвести до економії місця.

Використання атрибутів може підтримувати XML конкурентоспроможним JSON. Див. Розмітку жиру: Обрізання міфу про жирову розмітку по одній калорії за раз .


Не лише ідентифікатори чи імена. Вони можуть містити розділені пробілами списки майже нічого.
Джон Сондерс

@JohnSaunders IDS або NAMES - це специфічні типи DTD (я думаю, теж XML-схема), які підтримуються на низькому рівні більшістю процесорів XML. Якщо обробляється прикладним рівнем замість бібліотек XML, будь-які дані символьних символів працюють (розділені значення чи будь-що інше).
бріанарі

Особисто тому, що ти не можеш означати, що ти повинен.
Ланкімарт

1
@Lankymart Як я вже говорив, я просто виправляв некоректну інформацію (чомусь це було високо). Бінарні дані зазвичай взагалі не належать до XML.
бріанарі

1

Мене завжди дивують результати таких видів дискусій. Для мене існує дуже просте правило для визначення того, чи належать дані в атрибуті або як вміст, і це чи мають дані підструктуру, що може переміщуватися.

Так, наприклад, текст без розмітки завжди належить до атрибутів. Завжди.

Списки належать до підструктури чи змісту. Текст, який з часом може включати вбудований структурований підміст, належить до змісту. (На мій досвід, цього тексту - тексту з розміткою - при використанні XML для зберігання або обміну даними порівняно мало).

XML-схема, написана таким чином, є стислою.

Кожного разу, коли я бачу подібні випадки <car><make>Ford</make><color>Red</color></car>, я собі думаю: "гей, чи думав автор, що в елементі" make "з'являться під-елементи?" <car make="Ford" color="Red" />значно читабельніший, не виникає сумнівів у тому, як обробляти пробіли тощо.

Враховуючи лише правила поводження з пробілами, я вважаю, що це було чітким наміром дизайнерів XML.


одне з небагатьох пояснень, які я можу прочитати. поняття не маю, чи це гарна ідея ... але, принаймні, я розумію суть;)
Thufir

0

Це дуже ясно в HTML, де відмінності атрибутів та розмітки добре видно:

  1. Усі дані знаходяться між розміткою
  2. Атрибути використовуються для характеристики цих даних (наприклад, формати)

Якщо у вас просто чисті дані як XML, є менш чітка різниця. Дані можуть стояти між розміткою або як атрибути.

=> Більшість даних повинні стояти між розміткою.

Якщо ви хочете використовувати тут атрибути: Ви можете розділити дані на дві категорії: Дані та "Метадані", де метадані не є частиною запису, ви хочете представити, але такі речі, як "Формат версія", "Створена дата" тощо.

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

Можна також сказати: "Використовуйте атрибути для характеристики тегу, використовуйте теги для надання самих даних".


-1

Я згоден з feenster. Якщо не можете, тримайтеся подалі від атрибутів. Елементи є зручними для еволюції та більш взаємодіючими між наборами інструментів веб-служб. Ви ніколи не знайдете ці набори інструментів, які б серіалізували ваші запити / відповіді, використовуючи атрибути. Це також має сенс, оскільки наші повідомлення - це дані (а не метадані) для інструментарію веб-служб.


-1

Атрибути з часом легко можуть бути важкими для управління, довіряйте мені. я завжди тримаюся подалі від них особисто. Елементи набагато чіткіші та зручніші для читання / користування як аналізаторами, так і користувачами.

Єдиний раз, коли я коли-небудь використовував їх, було визначити розширення файлу URL-адреси активу:

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

Я думаю, якщо ви знаєте, що 100% атрибут не потрібно буде розширювати, ви можете їх використовувати, але скільки разів ви це знаєте.

<image>
  <url>wank.jpg</url>
  <fileType>gif</fileType>
</image>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.