Атрибут 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
Лорен Холст,

5
+1 за «... спор был о том, что на самом деле было метаданными».
Удержано

Обратите внимание на имена тегов в нижнем регистре с дефисами: stackoverflow.com/questions/1074447/…
Ben

Ответы:


145

Я использую это правило:

  1. Атрибут - это нечто автономное, то есть цвет, идентификатор, имя.
  2. Элемент - это то, что имеет или может иметь собственные атрибуты или содержать другие элементы.

Так что ваш близок. Я бы сделал что-то вроде:

РЕДАКТИРОВАТЬ : Обновлен оригинальный пример на основе обратной связи ниже.

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

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

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

2
@donroby - Извините, это была бы моя ошибка в общении. Под экранированием я имею в виду кодирование XML. '<' = & lt; и т. д. Мне кажется странным выбирать между атрибутом или элементом, основанным на символах, составляющих контент, а не на смысле контента.
micahtan

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Атрибут with по- прежнему имеет только одно значение, представляющее собой список некоторых типов данных, разделенных пробелами. Разделительные символы являются фиксированными, поэтому вы не можете иметь несколько значений, если одно значение требуемого типа данных может содержать пробелы. Это исключает возможность наличия, например, нескольких адресов в одном атрибуте «адрес».
Яссо

7
«Атрибуты труднее манипулировать программным кодом» - с этим нельзя согласиться. На самом деле я обнаружил, что все наоборот. Это не достаточно разницы, чтобы действительно заявить в любом случае.
Пол Александр

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

37

«XML» означает «расширяемый язык разметки ». Язык разметки подразумевает, что данные представляют собой текст, размеченный метаданными о структуре или форматировании.

XHTML - это пример XML, использованного так, как это было задумано:

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

Здесь различие между элементами и атрибутами очевидно. Текстовые элементы отображаются в браузере, а атрибуты - это инструкции о том, как их отображать (хотя есть несколько тегов, которые не работают таким образом).

Путаница возникает, когда XML используется не как язык разметки, а как язык сериализации данных , в котором различие между «данными» и «метаданными» является более расплывчатым. Таким образом, выбор между элементами и атрибутами является более или менее произвольным, за исключением вещей, которые не могут быть представлены с атрибутами (см. Ответ Фенстера).


32

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

XML это все о согласии. Сначала обратитесь к любым существующим XML-схемам или установленным соглашениям в вашем сообществе или отрасли.

Если вы действительно находитесь в ситуации, когда нужно определить свою схему с нуля, вот несколько общих соображений, которые должны дать информацию о решении « элемент против атрибута» :

<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.
  • Business Date, DateTime и цифры (например, количество, сумма и ставка) должны быть элементами.
  • Элементы нерабочего времени, такие как последнее обновление, срок действия которых истекает, должны быть атрибутами.
  • Номера для бизнеса, такие как хэш-коды и индексы, должны быть атрибутами. * Используйте элементы, если тип будет сложным.
  • Используйте атрибуты, если значение является простым типом и не повторяется.
  • xml: id и xml: lang должны быть атрибутами, ссылающимися на схему XML
  • Предпочитайте атрибуты, когда это технически возможно.

Предпочтение атрибутам заключается в следующем:

  • уникальный (атрибут не может появляться несколько раз)
  • порядок не имеет значения
  • вышеуказанные свойства являются наследуемыми (это то, что модель содержимого «все» не поддерживает в текущем языке схемы)
  • бонус в том, что они менее многословны и используют меньше пропускной способности, но на самом деле это не причина предпочитать атрибуты элементам.

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

Если XML-схема начинает разрешать ограничение или расширение модели содержимого «все», я бы, вероятно, отбросил ее


8

Если вы сомневаетесь, KISS - зачем смешивать атрибуты и элементы, когда у вас нет четкой причины использовать атрибуты. Если позже вы решите определить XSD, это тоже будет чище. Тогда, если вы даже позже решите сгенерировать структуру класса из вашего XSD, это будет также проще.


8

Универсального ответа на этот вопрос нет (я принимал активное участие в создании спецификации W3C). XML может использоваться для многих целей - текстовые документы, данные и декларативный код являются тремя наиболее распространенными. Я также часто использую его в качестве модели данных. Есть аспекты этих приложений, где атрибуты являются более распространенными, а другие, где дочерние элементы являются более естественными. Существуют также функции различных инструментов, которые облегчают или затрудняют их использование.

XHTML - это одна область, где атрибуты используются естественным образом (например, в классе = '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

Просто пара исправлений к какой-то плохой информации:

@ Джон Баллинджер: Атрибуты могут содержать любые символьные данные. <> & "'необходимо экранировать к & lt; & gt; & amp;" и "соответственно. Если вы используете библиотеку XML, она позаботится об этом за вас.

Черт, атрибут может содержать двоичные данные, такие как изображение, если вы действительно хотите, просто с помощью base64-кодирования его и превращения его в data: URL.

@feenster: атрибуты могут содержать разделенные пробелами несколько элементов в случае IDS или NAMES, которые будут включать числа. Nitpicky, но это может в конечном итоге сэкономить место.

Использование атрибутов может обеспечить конкурентоспособность XML с JSON. См. Жирная разметка: обрезка жировой разметки Миф по одной калории за раз .


Не только идентификаторы или имена. Они могут содержать разделенные пробелами списки практически всего.
Джон Сондерс

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

Лично, то, что ты можешь, не значит, что ты должен.
Lankymart

1
@Lankymart Как я уже сказал, я просто исправлял некоторую неверную информацию (по некоторым причинам она была высокой). Двоичные данные обычно не принадлежат XML.
brianary

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.