Атрибуты XML по сравнению с элементами [дубликат]

С помощью вы можете обрабатывать ссылку на интерфейс как одну вверху в иерархии.

С помощью вы можете обрабатывать ссылку на интерфейс как одну вниз в hiearchy.

Позвольте мне объяснить это на более английском языке.

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

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

Однако, если у вас есть только список рыб, но вам нужно относиться к ним как к животные, это работает? Интуитивно, он должен работать, но в C # 3.0 и ранее этот фрагмент кода не будет компилироваться:

IEnumerable animals = GetFishes(); // returns IEnumerable

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

Другими словами, компилятор не может гарантировать, что это недопустимо:

animals.Add(new Mammal("Zebra"));

Таким образом, компилятор просто отказывается компилировать ваш код. Это ковариация.

Давайте посмотрим на контравариантность.

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

В C # 3.0 и ранее это не компилируется:

List fishes = GetAccessToFishes(); // for some reason, returns List
fishes.Add(new Fish("Guppy"));

Здесь компилятор мог разрешить эту часть кода, даже если метод возвращает List просто потому, что все рыбы являются животными, поэтому, если мы просто изменили типы на это:

List fishes = GetAccessToFishes();
fishes.Add(new Fish("Guppy"));

Тогда это сработает, но компилятор не может определить, что вы не пытаетесь это сделать:

List fishes = GetAccessToFishes(); // for some reason, returns List
Fish firstFist = fishes[0];

Поскольку список на самом деле является списком животных, это не разрешено.

Таким образом, противоречие и коразмерность - это то, как вы обрабатываете ссылки на объекты и что вам разрешено с ними.

Ключевые слова in и out в C # 4.0 специально маркируют интерфейс как тот или другой. С помощью in вы можете поместить общий тип (обычно T) в input -позиции, что означает аргументы метода и свойства только для записи.

С помощью out, вы можете поместить общий тип в output -позиции, которые являются значениями возврата метода, свойствами только для чтения и параметрами метода out.

Это позволит вы делаете то, что намерено делать с кодом:

IEnumerable animals = GetFishes(); // returns IEnumerable
// since we can only get animals *out* of the collection, every fish is an animal
// so this is safe

List имеет как входы, так и выходы на T, поэтому он не является ни ковариантным, ни контравариантным, но интерфейс что позволило вам добавлять объекты, например:

interface IWriteOnlyList
{
    void Add(T value);
}

позволит вам сделать это:

IWriteOnlyList fishes = GetWriteAccessToAnimals(); // still returns
                                                            IWriteOnlyList
fishes.Add(new Fish("Guppy")); <-- this is now safe

Вот несколько видеороликов, которые показывают понятия:

Вот пример:

namespace SO2719954
{
    class Base { }
    class Descendant : Base { }

    interface IBibbleOut { }
    interface IBibbleIn { }

    class Program
    {
        static void Main(string[] args)
        {
            // We can do this since every Descendant is also a Base
            // and there is no chance we can put Base objects into
            // the returned object, since T is "out"
            // We can not, however, put Base objects into b, since all
            // Base objects might not be Descendant.
            IBibbleOut b = GetOutDescendant();

            // We can do this since every Descendant is also a Base
            // and we can now put Descendant objects into Base
            // We can not, however, retrieve Descendant objects out
            // of d, since all Base objects might not be Descendant
            IBibbleIn d = GetInBase();
        }

        static IBibbleOut GetOutDescendant()
        {
            return null;
        }

        static IBibbleIn GetInBase()
        {
            return null;
        }
    }
}

Без эти метки могут составить следующее:

public List GetDescendants() ...
List bases = GetDescendants();
bases.Add(new Base()); <-- uh-oh, we try to add a Base to a Descendant

или это:

public List GetBases() ...
List descendants = GetBases(); <-- uh-oh, we try to treat all Bases
                                               as Descendants

70
задан skaffman 5 October 2008 в 21:30
поделиться

8 ответов

Один из лучшего продуманного элемента по сравнению с аргументами атрибута прибывает из британские инструкции GovTalk . Это определяет методы моделирования, используемые для связанных с правительством обменов XML, но это стоит на его собственных достоинствах и достойно рассмотрения.

Схемы ДОЛЖНЫ быть разработаны так, чтобы элементы были основными держателями информационного содержания в экземплярах XML. Атрибуты больше подходят для содержания вспомогательных метаданных †“простые объекты, предоставляющие больше информации о содержании элемента. Атрибуты не ДОЛЖНЫ использоваться для квалификации других атрибутов, где это могло вызвать неоднозначность.

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

дата рождения А могла бы быть представлена в сообщении как:

 <DateOfBirth>1975-06-03</DateOfBirth> 

Однако больше информации могло бы быть запрошено, такой как, как та дата рождения была проверена. Это могло быть определено как атрибут, заставив элемент в сообщении быть похожим:

<DateOfBirth VerifiedBy="View of Birth Certificate">1975-06-03</DateOfBirth> 

следующее было бы несоответствующим:

<DateOfBirth VerifiedBy="View of Birth Certificate" ValueSet="ISO 8601" Code="2">1975-06-03</DateOfBirth>   

не ясно здесь, квалифицирует ли Код VerifiedBy или атрибут ValueSet. Более соответствующее представление было бы:

 <DateOfBirth>    
   <VerifiedBy Code="2">View of Birth Certificate</VerifiedBy>     
   <Value ValueSet="ISO 8601">1975-06-03</Value>
 </DateOfBirth>
18
ответ дан gilbertbw 7 November 2019 в 09:26
поделиться

Существует статья, названная" Принципы дизайна XML: Когда использовать элементы по сравнению с атрибутами " на веб-сайте IBM.

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

я время от времени отношусь к этой статье, поскольку я разрабатываю различные структуры XML. Надо надеяться, это будет полезно другим также.

редактирование - От сайта:

Принцип базового содержания

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

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

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

Принцип структурированной информации

, Если информация выражается в структурированной форме, особенно если структура может быть расширяема, используйте элементы. С другой стороны: Если информация выражается как атомарный маркер, используйте атрибуты. Элементы являются расширяемым механизмом для выражения структуры в XML. Почти все инструменты обработки XML разработаны на основе этого факта, и если Вы сломаете структурированную информацию правильно в элементы, Вы найдете, что Ваши инструменты обработки дополняют Ваш дизайн, и что Вы, таким образом, получаете производительность и пригодность для обслуживания. Атрибуты разработаны для выражения простых свойств информации, представленной в элементе. Если Вы работаете против базовой архитектуры XML shoehorning структурированной информацией в атрибуты, можно получить некоторую показную краткость и удобство, но Вы, вероятно, заплатите в затратах на обслуживание.

Даты являются хорошим примером: дата зафиксировала структуру и обычно действует как единственный маркер, таким образом, это имеет смысл как атрибут (предпочтительно выраженный в ISO 8601). Представление имен, с другой стороны, является случаем, где я видел, что этот принцип удивляет разработчиков. Я вижу имена в атрибутах много, но я всегда утверждал, что имена должны быть в содержании элемента. Имя имеет удивительно переменную структуру (в некоторых культурах, которые можно вызвать беспорядок или преступление путем исключения honorifics или принятия порядка частей имен). Имя является также редко атомарным маркером. Как пример, иногда можно хотеть искать или отсортировать по имени и иногда по фамилии. Я должен указать, что это столь же проблематично к рожку для обуви полное имя в содержание единственного элемента, как это должно выразиться в атрибуте.

38
ответ дан dbasnett 7 November 2019 в 09:26
поделиться

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

, Например, я предпочитаю.....

<?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>
7
ответ дан Rory Becker 7 November 2019 в 09:26
поделиться

Лично мне нравится использовать атрибуты для простых однозначных свойств. Элементы (очевидно), более подходят для составных типов или повторенных значений.

Для однозначных свойств, вывода атрибутов к более компактному XML и более простому обращению в большинстве API.

17
ответ дан Jon Skeet 7 November 2019 в 09:26
поделиться

Выезд Элементы по сравнению с атрибутами Ned Batchelder.

Хорошее объяснение и хороший список преимуществ и недостатки Элементов и Атрибутов.

Он сводит его к:

Рекомендация: Используйте элементы для данных, которые будут произведены или использованы бизнес-приложением и атрибутами для метаданных.

Важный: см. комментарий @maryisdead ниже для дальнейшего разъяснения.

4
ответ дан Dhaust 7 November 2019 в 09:26
поделиться

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

Атрибуты применимы в доменах, где они отображаются на структуры данных, которые следуют тем правилам: имена и значения свойств на объекте, столбцов подряд таблицы, записей в словаре. (Но не, если свойства не являются всеми типами значения или записями в словаре, не строки.)

2
ответ дан Robert Rossney 7 November 2019 в 09:26
поделиться

Я склонен использовать элементы, когда это - данные, которые читатель должен был бы знать и атрибуты, когда это только для обработки (например, идентификаторы). Это означает, что я редко использую атрибуты, поскольку большинство данных относится к смоделированному домену.

1
ответ дан dommer 7 November 2019 в 09:26
поделиться

Вот еще одна стратегия, которая может помочь отличить элементы от атрибутов: подумайте объектов и имейте в виду MVC.

Объекты могут иметь члены (объектные переменные) и свойства (члены с установщиками и получателями). Свойства очень полезны с дизайном MVC, позволяя механизм уведомления об изменениях.

Если выбрано это направление, атрибуты будут использоваться для внутренних данных приложения, которые не могут быть изменены пользователем; классические примеры будут ID или DATE_MODIFIED. Таким образом, элементы будут использоваться для данных, которые могут быть изменены пользователями.

Таким образом, следующее будет иметь смысл, учитывая, что библиотекарь сначала добавляет элемент книги (или журнал), а затем может редактировать его имя ISBN автора и т. Д .:

<?xml version="1.0" encoding="utf-8"?>
<item id="69" type="book">
    <authors count="1">
        <author>
            <name>John Smith</name>
        <author>
    </authors>
    <ISBN>123456790</ISBN>
</item>
1
ответ дан 24 November 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: