IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  XML  >

Совет: Вложенные элементы или атрибуты

Вопросы проектирования XML-форматов

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: простой

David Mertz, Исследователь, Gnosis Software, Inc.

01.11.2001

В данной статье рассматриваются рекомендации по выбору использования атрибутов тегов или вложенных элементов для представления данных. Вы узнаете о том, что необходимо учитывать при проектировании DTD, схемы или нерегламентируемого XML-формата. Вы также узнаете, когда атрибуты и вложенные элементы являются взаимозаменяемыми, а когда нет. Рассматриваемые вопросы иллюстрируются примерами кода.

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

Единственным случаем, когда не требуется решать вопросы размещения данных, является случай, когда вы четко следуете спецификации XML-диалекта. Эта спецификация может быть задана в виде DTD или W3C XML-схемы, или же описана неформально или с помощью примера. Если перед вами не стоит такой проблемы выбора, можно пропустить рекомендации, приведенные в этой статье. Между тем, разработчикам иногда приходится самостоятельно разрабатывать точный XML-диалект. В таком случае – эта статья для вас.

Следует помнить, что существует различие между XML-документами, которые должны быть просто правильно сформированными, и теми, что обязаны быть валидными согласно DTD/Схеме. Валидность является более строгим критерием. Она позволяет вам требовать присутствия определенных данных и их структуризации. По этой же самой причине приходится прикладывать гораздо больше усилий для того, чтобы процесс производства данного документа соответствовал требованиям валидности. Оба подхода обладают своими преимуществами. Использование DTD усложняет задачу выбора элементов/атрибутов, однако в обоих случаях существуют альтернативы. Эти альтернативы описываются далее.

Важен ли порядок следования данных

При использовании DTD вложенные элементы, в отличие от атрибутов, являются строго упорядоченными. Если XML-документ является всего лишь правильно сформированным, порядок следования элементов в нем можно изменять. В этом случае любой тег может находиться внутри любого другого тега. В обоих случаях атрибуты обычно лучше использовать для неупорядоченных данных. Для XML-документов с DTD использование атрибутов для этого типа данных является почти обязательным.

К примеру, представьте себе список контактов, каждый из которых должен содержать имя, возраст и номер телефона. С точки зрения логики здесь нет таких ограничений, по которым, к примеру, возраст должен предшествовать телефонному номеру, то есть атрибуты здесь не должны быть упорядочены. В данном случае их использование скорее более интуитивно. Сравните два XML-документа из листингов 1 и 2:


Листинг 1. Использование атрибутов для списка контактов
                
<?xml version="1.0" ?>
<!DOCTYPE contacts SYSTEM "attrs.dtd" >
<contacts>
  <contact
     name="Jane Doe"
     age="74"
     telephone="555-3412" />
  <contact name="Chieu Win" telephone="555-8888" age="44" />
</contacts>				
			


Листинг 2. Использование вложенных элементов для списка контактов
                
<?xml version="1.0" ?>
<!DOCTYPE contacts SYSTEM "subelem.dtd" >
<contacts>
  <contact>
    <name>Jane Doe</name>
    <age>74</age>
    <telephone>555-3412</telephone>
  </contact>
  <contact>
    <name>Chieu Win</name>
    <telephone>555-8888</telephone>
    <age>44</age>
  </contact>
</contacts>		
			

Представим теперь DTD, соответствующий каждому из этих XML-форматов. Для Листинга 1 он должен выглядеть примерно так, как показано в Листинге 3.


Листинг 3. DTD для списка контактов с использованием атрибутов
                
<!ELEMENT contacts (contact*)>
<!ELEMENT contact EMPTY>
<!ATTLIST contact name      CDATA #REQUIRED
                  age       CDATA #REQUIRED
                  telephone CDATA #REQUIRED >
			

В случае с использованием вложенных элементов, DTD будет выглядеть так, как показано в Листинге 4.


Listing 4. DTD для списка контактов с использованием вложенных элементов
                
<!ELEMENT contacts  (contact*)>
<!ELEMENT contact   (name,age,telephone)>
<!ELEMENT name      (#PCDATA)>
<!ELEMENT age       (#PCDATA)>
<!ELEMENT telephone (#PCDATA)>
			

Очевидным недостатком DTD, представленным в Листинге 4 является то, что простой пример из Листинга 2 не является валидным при использовании данного DTD (даже если он содержит необходимые данные). Здесь вложенные элементы являются неупорядоченными. В таблице справа показано, как можно использовать неупорядоченные элементы с DTD, однако пока не существует других непреодолимых причин, для неупорядоченных данных лучше всего воспользоваться определением атрибутов.



В начало


Возможность нахождения многочисленных данных на одном уровне

Если в одном объекте неоднократно встречаются одинаковые типы данных, предпочтительней использовать вложенные элементы. К примеру, в сценарии со списком контактов объект contacts содержит в себе множество объектов contact. В этом случае становится ясно, что каждый контакт должен быть описан в элементе, дочернем к элементу contacts.

В реальной жизни разработчики часто уходят от такого принципа проектирования. К примеру, вы обнаружили, что у каждого Flazbar имеется прикрепленный к нему flizbam (который описывается элементом данных). Похоже, что очевидным выбором будет сохранить дополнительное словесное наполнение вложенного элемента и создать атрибутflizbam для тега Flazbar. Между тем, после написания рабочего кода для обработки нескольких Flazbar вы обнаружили, что в некоторых ситуациях у Flazbar могут быть два flizbam. Проблему решить просто - достаточно внести небольшие изменения в коде и просто переписать DTD следующим образом:

<!ATTLIST Flazbar flizbam   CDATA #REQUIRED
                  flizbam2  CDATA #IMPLIED>				
			

После такого исправления будут валидны, как старые, так и новые XML-документы. Но спустя некоторое время вы обнаруживаете, что у Flazbar может быть и третий flizbam...

Согласитесь, трудно не соблазниться этим коварным принципом проектирования. Данные и объекты со временем развиваются, вследствие чего может возникать потребность в многократном повторении отдельных сущностей. По этой причине некоторые XML-программисты избегают использования атрибутов. Вам следует тщательно продумать на этапе проектирования, могут ли у отдельного элемента данных позднее появится элементы того же уровня. Если такая возможность существует, вам следует с самого начала использовать вложенные элементы. Если вы уверены в том, что объект данных будет оставаться уникальным, используйте атрибуты.



В начало


Об обязательности сохранения пробелов

Моделирование неупорядоченных вложенных элементов

Вы можете создать DTD, который делает XML-документ из Листинга 2 валидным путем включения определения, как это сделано в листинге.

DTD гибко определяющий вложенные элементы списка контактов

Впрочем, DTD, указанный ранее, предоставляет слишком большую гибкость. В этом случае, у элементов contact могут отсутствовать элементы name, а также быть несколько элементов age, что нарушает семантические требования. Для решения поставленной задачи требуется довольно громоздкое определение, приведенное ниже.

Громоздкое, но точное определение DTD для элементов списка контактов

Этот DTD безобразен, и при добавлении новых вложенных элементов его безобразность увеличивается в геометрической прогрессии. Кроме того, создание более строгого DTD, чем это семантически необходимо, для производителей данных является нежелательным (например, задание DTD для первого вложенного элемента).

После нормализации атрибутов можно считать, что каждый атрибут будет отделен от соседних пробелом. Однако это единственное, на что можно рассчитывать. Для удобства чтения можно без особых проблем добавить к длинным значениям атрибутов вертикальные или горизонтальные пробелы (на самом деле вы должны это сделать). Однако, после обработки XML-парсером форматирование XML-кода скорее всего изменится.

Если сохранение пробелов имеет значение, лучше воспользоваться вложенными элементами. В качестве примера можно привести ситуации, когда необходимо представить что-нибудь вроде исходного кода или, скажем, стихов, где необходимо строго выдерживать интервал.



В начало


Насколько важна читабельность?

В идеале, XML должен быть форматом, предназначенным для чтения компьютером, а не человеком. Однако, к счастью или наоборот, программисты – тоже люди, и в обозримом будущем им придется тратить массу времени на чтение, написание и отладку XML-файлов. Поистине, это мучительный процесс – чтение XML-файла, отформатированного компьютером (пробелы отсутствуют или они бессмыслены).

Лично мне гораздо легче читать и писать XML со структурой, где преимущественно используются атрибуты, а не вложенные элементы. Сравните Листинг 1 и Листинг 2 и вы поймете, что я имею в виду. Оба из них не так уж сложно читать, однако Листинг 2, демонстрирующий использование атрибутов воспринимать проще. Его также проще написать, поскольку не нужно беспокоиться об упорядочивании вложенных элементов.



В начало


Заключение

В данной статье мы представили некоторые случаи, демонстрирующие использование вложенных элементов и атрибутов. Понимание указанных здесь принципов может помочь вам в создании более четких и понятных форматов XML-документов. К сожалению, иногда в реальной ситуации мы сталкиваемся со множеством обстоятельств, указывающих на противоположенные решения. Зачастую структура данных изменяется настолько, что предыдущие мотивации уже становятся недействительными. Используйте наши рекомендации тогда, когда это возможно и, прежде всего, полагайтесь на здравый смысл.



Ресурсы



Об авторе

Author photo

Для написания статьи о структурированных форматах документов David Mertz использовал полностью неструктурированный мозг. Связаться с ним можно по адресу mertz@gnosis.cx. Его жизнь рассматривается на сайте http://gnosis.cx/dW/.




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



ДаНетНе знаю
 


 


12345
 


В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.

    IBM в России Конфиденциальность Контакты