Эту статью стоило / можно было написать ещё 10/15 лет назад, когда XML был в большей степени на хайпе, чем сейчас. Сейчас, к счастью, его постепенно вытесняют другие текстовые форматы, более удобные в использовании. Но лучше написать поздно, чем никогда.
Любовь
XML, который мы так любим, был придуман ещё в конце 1990-х на фоне совершенно заслуженного успеха HTML. А в начале / середине 2000-х начался настоящий хайп вокруг этого формата — были выпущены десятки книг, написаны сотни восторженных статей. XML-евангелисты прочили ему захват мира; казалось, ещё немного — и вообще всё, что мы можем себе представить и помыслить в цифровом мире (ну разве что кроме видео и картинок) будет одним сплошным XML-документом (Как в старом фильме «Ничего не будет: ни кино, ни театра, ни книг, ни газет – одно сплошное телевидение»).
Мало того, был анонсирован и даже воплощён в реальности целый набор специализированных чипов, которые были заточены именно на обработку XML (DataPower XML Accelerator, Tarari XML Content Processor, Ternary XML Accelerator, Xelerator XML Accelerator, XA35 XML Accelerator).
На базе XML был разработан целый ряд других форматов и стандартов: SOAP, WSDL, SVG, MathML и т.п., включая форматы для хранения документов и электронных таблиц: OpenDocument Format (ODF), Office Open XML (OOXML), Excel Open XML (XLSX), OpenDocument Spreadsheet (ODS), GNUMERIC и т.д., а также для записи нот: MusicXML, MEI, Sibelius, Finale, MuseScore, MIDI XML и т.п.
Глубокое знание XML со всеми XML-cхемами, зачастую, входило, да и сейчас входит, в список обязательных требований на вакансии программистов.
В значительной доле самых разных проектов до сих пор конфиги и прочие настройки хранятся в XML.
И ненависть
Однако, ещё лет 20 назад, когда начинался весь этот хайп вокруг XML, мне этот формат не приглянулся и я никогда не использовал его в своих проектах ни в каком качестве (разве только вынужденно, если приходилось обращаться к чужим API, которые на основе XML).
Причин, почему он ещё тогда не приглянулся, масса, но вот лишь некоторые из них, основные:
Чудовищная избыточность
Как минимум, почти везде нужны закрывающие теги, одно только это раздувает XML-документы в 2 раза. Ну, это понятная история и лежит на поверхности, много ума не надо, чтобы это заметить.
Чтобы как-то скрыть этот «нюанс» почти все форматы для хранения документов в XML сейчас архивируются. Документы представляют из себя фактически ZIP-файл с набором XML-файлов внутри. Как говорится, «сомнительно, но окей».
Неоднозначность преобразования в/их из встроенных структур данных ЯП
В современных высокоуровневых / динамических языках программирования (на примере Python, JS, PHP, Perl, Ruby и т.п.), за редким исключением, все структуры данных представляют из себя комбинацию скаляров (переменных, хранящих одно значение какого-то атомарного типа данных), списков и словарей (ассоциативных массивов). Для хранения / обработки данных внутри ЯП в основном используются комбинации / деровидные структуры из этих структур данных. Другие более хитрые структуры данных используются редко и только когда это зачем-то действительно сильно нужно.
Так вот, не существует единственного и взаимооднозначного способа преобразования таких структур данных в/из XML. Таких способов преобразования существует бесконечное количество (счётное, но бесконечное множество вариантов), поэтому для того, чтобы гонять данные туда/сюда нужны какие-то дополнительные соглашения / схемы. Просто так задампить данные в одном месте и "раздампить" в другим без доп. соглашений — невозможно, а это дополнительная интеллектуальная работа, время, объём кода и т.п.
Это и есть моя главная претензия к XML.
Сложность в определении схемы
Этот пункт отчасти вытекает из предыдущего. Для того, чтобы как-то упорядочить хаос и из бесконечного множества способов преобразования данных из стандартных структур данных ЯП выделить один единственно правильный способ, в том числе для этого нужны XML-схемы: отдельные документы (которые сами по себе часто являются XML-документами), где описана валидная структура интересующего нас вида XML-документов. Конечно, XML-схемы решают и другие задачи, включая контроль типов данных и сами структуры даных.
Этих форматов XML-схем также существует целый зоопарк: DTD, XSD, RelaxNG, Schematron, NVDL, RELAX и т.п., каждый со своими преимуществами и недостатками / неудобствами.
Конечно, наличие и необходимость подобных схем с описаниями ограничений структур и типов данных есть не только в мире XML, существуют подобные схемы и в мире JSON (JSON Schema, JSON LD) и YAML (YAML Schema, RAML), но используются там схемы гораздо реже (в основном только при реализации API) в силу более простой структуры базовых форматов и отсутствия неоднозначности преобразования, описанного в предыдущем пункте.
Человекочитаемость?
Изначально главным поинтом в пропаганде XML на старте звучала «человекопонятность» — человек на любом этапе сможет глазками посмотреть и проанализировать документ и понять, если что-то пойдёт не так.
Что же мы видим в реальности? Правильный ответ:
<pic:cNvPicPr><a:picLocks noChangeAspect="1" noChangeArrowheads="1"/></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed="rId4"><a:extLst><a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}"><a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr bwMode="auto"><a:xfrm><a:off x="0" y="0"/><a:ext cx="391" cy="390"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln><a:extLst><a:ext uri="{909E8E84-426E-40DD-AFC4-6F175D3DCCD1}"><a14:hiddenFill xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"><a:solidFill><a:srgbClr val="FFFFFF"/></a:solidFill></a14:hiddenFill></a:ext><a:ext uri="{91240B29-F687-4F45-9708-019B960494DF}"><a14:hiddenLine xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" w="9525"><a:solidFill><a:srgbClr val="000000"/></a:solidFill><a:miter lim="800000"/><a:headEnd/><a:tailEnd/></a14:hiddenLine></a:ext></a:extLst></pic:spPr></pic:pic><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="32" name="docshape3"/><pic:cNvPicPr><a:picLocks noChangeAspect="1" noChangeArrowheads="1"/></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed="rId5"><a:extLst><a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}"><a14:useLocalDpixmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr bwMode="auto"><a:xfrm><a:off x="6" y="0"/><a:ext cx="385" cy="362"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln><a:extLst><a:ext uri="{909E8E84-426E-40DD-AFC4-6F175D3DCCD1}">
И это ещё вариант «лайт» — хард было лень искать. Всё в одну строку, без единого пробела. Ну понятно — экономим место же и ускоряем обработку. В подобной ситуации XML никаким образом не получает преимуществ в человекопонятности в сравнении с альтернативами.
Сравним ЭТО, например, с YAML, где сами правила форматирования (как и в Python, например), делают просто невозможным превращение документа в нечитаемый треш:
---
person:
name: John Doe
age: 30
email: john.doe@example.com
address:
street: 123 Main St
city: Anytown
state: CA
zip: 12345
phone_numbers:
- type: home
number: 555-1234
- type: work
number: 555-5678
employment:
- company: Acme Inc.
position: Software Engineer
start_date: '2015-07-01'
end_date: '2018-12-31'
- company: XYZ Corp.
position: Senior Software Engineer
start_date: '2019-01-01'
Скажут — «ну зачем тебе эта человекопонятность, всё равно всё делают машины!».
Не соглашусь. К примеру, я активно работаю с различными форматами нотной записи и зачастую в нотах бывают ошибки, например, при конвертации между форматами или в самой программе что-то пошло не так. Или мне нужно выполнить действие с нотами, которое не поддерживается пока самой программой (просто что-то не реализовано в интерфейсе), я могу просто открыть файл и отредактировать ручками нужные мне вещи.
В случае большого документа, например, в форматах MusicXML или MuseScore, редактировать XML, где, докучи, ещё и форматирование сильно едет (поскольку о красивом выравнивании XML в файлах разработчики, по понятным причинам не беспокоятся) — это становится грустно. Так вот, если бы эти форматы были не на основе XML, а на основе, скажем, YAML — анализировать и редактировать их руками было бы В РАЗЫ (если не на порядок) легче.
«Не всё так однозначно»
Не буду заниматься крючкотворством и концентрироваться на более мелких недочётах XML, приведённых аргументов про неудобство этого формата, вполне достаточно.
Однако, на мой взгляд, у XML остаются ниши, где он может быть, по прежнему, одним из лучших выборов. В первую очередь, это RICH-text в различных его вариантах, и такие форматы как ePUB, RSS, DocBook вполне имеют право на существование. Там, где относительно много текста и относительно мало тегов / служебных данных, XML — прекрасный выбор.
Собственно XHTML (тот же HTML, но с дополнительными ограничениями, делающими его валидным XML-документом) — прекрасный пример «как надо».
Что же делать, куда бежать?
Ответ прост:
Если вам нужен человекочитаемый / чиловекописуемый конфиг — используйте YAML. Меньше избыточности, гораздо лучшая «человекопонятность», очень удобно редактировать руками.
Ну или, на худой конец, TOML, если YAML вам претит: свободы и разгула вариаций меньше, строгости больше.
Если вы обмениваетесь данными между приложениями / сервисами (по API или как-то ещё), ваш выбор — JSON.
Если вы храните «документы» в файлах — также можете использовать любой из этих двух форматов в зависимости от того, нужна бОльшая человекочитаемость (тогда YAML) или большая компактность (JSON).
(В обоих случаях мы имеем дело с гораздо более простыми форматами, которые, при этом, взаимооднозначным образом конвертируются в / из структур данных высокоуровневых языков программирования.)
Если вы создаёте RICH-text документы, где не нужно сверхсложное форматирование — используйте MarkDown или аналоги.
Вывод
Сейчас, к счастью для меня, XML теряет популярность в том числе по описанным мною выше причинам. Если он будет терять эту популярность ещё быстрее, в том числе благодаря этой статье — я буду счастлив.
Комментарии (48)
alhimik45
21.08.2024 10:45+4Поскольку json - это валидный yaml, никто не помешает зафигачить тоже самое на "yaml" в одну строку, если захочется
PikNic
21.08.2024 10:45+14XML — слишком многословен и неудобен, JSON вполне терпим, но отсутствие комментариев и запрет на trailing comma, серьёзно? YAML очевидно создан покусанными Питоном в терминальной стадии, иначе объяснить необходимость вручную высчитывать пробелы и помнить как они соотносятся с дефисами я не могу. А нормальные форматы то вообще завезут когда-нибудь?
С языками разметки не лучше — кто-то решил, что Markdown плох, завезли RST. Ну тут вообще цензурных слов нет, 90% работы по написанию документации уходит на борьбу с форматом и лишь 10% — на содержимое.
asdfddsa
21.08.2024 10:45+5А нормальные форматы то вообще завезут когда-нибудь?
Даже не надейтесь. )))) Я лет 25 сталкиваюсь с задачами чего-нибудь из одной БД взять и в другую БД положить. За все это время, никто ничего вменяемого не придумал. Тошнит от одной мысли, что нужно загрузить кем-то выгруженные данные, уже сразу представляешь кучку глюков и тупой рутины.
Недостатки XML зачастую являются его же достоинством. Попробуйте глазами разобрать скобки в JSON, если они криво отформатированы, где чего кончается, попробуй найди...
Mingun
21.08.2024 10:45+1Markdown плох, завезли RST
Вообще-то, reStructuredText (вы же его под RST имеете в виду) появился в 2002 году в виде PEP-287, а Markdown ажно на 2 года позже — в 2004. И честно говоря, первый выглядит гораздо стройнее, кроме того, он и фичастее второго (из коробки поддержка таблиц, разных типов сносок, списки, выделения текста — и не только жирный/курсив, а можно и свою семантику навесить, ссылки). К сожалению, как уже неоднократно показывала история, этого совершенно недостаточно, чтобы стать лидером в чём-либо…
vagon333
21.08.2024 10:45+8Критикуя предлагайте альтернативы.
Занимаюсь стандартами на банковские данные.
Для меких request/response вполне подходит JSON.
Для сложных структур альтернативу XML пока не нашли.Речь о 700+ таблицах, 5000+ колонках и 900+ связях между таблицами и массой метаданных.
Все это в 8 поддерживаемых версиях с 2011.
artptr86
21.08.2024 10:45+16В современных высокоуровневых / динамических языках программирования (на примере Python, JS, PHP, Perl, Ruby и т.п.), за редким исключением, все структуры данных представляют из себя комбинацию скаляров (переменных, хранящих одно значение какого-то атомарного типа данных), списков и словарей (ассоциативных массивов).
Это хорошо, но в языках со строгой статической типизацией (C++, Java, C#) структуры данных обычно представляют собой классы. И здесь появляется нюанс, что XML явно указывает типы структур в виде имён элементов, а такие форматы, как JSON и YAML — нет.
Отсюда очевидно, что неоднозначность преобразования из объектов языка программирования в «нетипизированные» форматы всё равно существует: сериализатор должен тем или иным способом сообщить тип объекта.
class Figure {} class Rectangle extends Figure {} class Circle extends Figure {} class Triangle extends Figure {} class Scene { List<Figure> figures; }
В XML это могло бы быть сериализовано как-то так:
<Scene> <Rectangle x="120" y="50" width="200" height="100" /> <Circle x="65" y="65" radius="40" /> <Triangle ... /> </Scene>
При десериализации автоматически был бы создан объект Scene, а также объекты фигур, которыми был бы заполнен список figures. Да, здесь есть неоднозначность, но всё выглядит достаточно просто.
В случае с JSON такая библиотека сериализации, как Jackson, может сделать подобного кадавра:
{ figures: [ "java.util.ArrayList", [ [ "com.example.Rectangle", { x: 120, y: 50, width: 200, height: 100 } ], [ "com.example.Circle", { x: 65, y: 65, radius: 40 } ], [ "com.example.Triangle", { ... } ] ] ] }
За такой код вас побьют любые адепты динамических языков. Поэтому есть вариант проще, но он тоже не универсальный:
{ figures: [ { type: "rectangle", x: 120, y: 50, width: 200, height: 100 }, { type: "circle", x: 65, y: 65, radius: 40 }, { type: "triangle", ... } ] }
на основе, скажем, YAML — анализировать и редактировать их руками было бы В РАЗЫ (если не на порядок) легче
В отношении YAML я бы никогда не использовал слово «легче»: это крайне нетривиальный формат, не имеющий ни однозначной спецификации, ни референсной реализации, из-за чего множество имплементаций несовместимо между собой, а отдельные нюансы могут попить много крови у всех использующих такой формат:
capitals: - country: ru name: Moscow - country: no name: Oslo
Oangai
21.08.2024 10:45+7если сформулировать коротко: программисты, использующие YAML или JSON, всё равно каждый раз вынуждены создавать какой-то свой внутренний валидатор, но не считают нужным его формально документировать, зачастую и не знают что это возможно. Схемы как XSD создавались как раз чтобы предоставить такое общедоступное формальное описание и позволить проверять документ сторонним валидатором. Одновременно, такая схема служила самодостаточной документацией для программиста принимающей стороны. Для "неявных" размазанных по коду схем программисту всё равно приходится документацию писать, только теперь без гарантий соответствия актуальной реализации.
artptr86
21.08.2024 10:45В качестве схемы данных сейчас могут использовать Swagger (есть и кодогенераторы из сваггера), но он тоже не очень однозначно мапится на целевые языки.
Oangai
21.08.2024 10:45на мой взгляд, изза того что современные схемы не смогли стать стандартом, от любой из них будет отдавать кустарщиной. Не то что бы их нельзя было использовать, можно конечно, свою функцию они выполнят, но каждый раз нужно аргументировать почему взяли вот ту, а не эту.
inkelyad
21.08.2024 10:45Схемы как XSD создавались как раз чтобы предоставить такое общедоступное формальное описание и позволить проверять документ сторонним валидатором. Одновременно, такая схема служила самодостаточной документацией для программиста принимающей стороны.
Только их сделали слишком мощными и поэтому не слишком совместимыми с представлением данных большинством языков программирования.
Скажем: Если в описании элемента есть choice - то маппинг в структуру данных языка почти наверняка будет иметь оба поля. И если попытаться воспользоваться сужением возможных полей элемента при помощи restriction ("то же самое, что X, но элементы a,b,c не используются", т.е. 'наследование наоборот') - то такого тоже не получится. Потому что какой язык умеет удалять функционал и поля из описанного типа/класса?
Oangai
21.08.2024 10:45+2какой язык умеет удалять функционал и поля из описанного типа/класса?
Языки с поддежкой контрактного программирования умеют именно это - ADA, Eiffel. Для остальных программистов было бы просто полезно однажды разобраться с этой теорией, чтобы было понимание проблематики, даже если их рабочий язык программирования это не поддерживает.
На своем примере: в середине 2000х работал на одном проекте медицинской информационной системы, отвечал за структуру базы данных, алгоритмы поиска и поточный импорт XML документов от множества больниц, довольно сложных и обьёмных. Генерировали документы не мы, левые производители больничного софта; госстандарт для этих документов в процессе дорабатывался, нам нужно было тоже оперативно учитывать изменения. Не будь у нас XSD, было бы просто нереально такой процесс без ошибок поддерживать, а так, то что у нас в бэкенде php5+mysql использовались, это на надежность уже никак не влияло.
Oangai
21.08.2024 10:45+1еще, тоже многие путают задачи сериализации с задачами описания структуры документа. Технически конечно одно в другое вполне транслируемо, но на практике есть нюанс: сериализация применяется для внутренних API, а формализованные документы для внешних, соответственно требования к ним принципиально разные. SOAP был как раз контрпримером, как не надо делать, применять тяжеловесную формализацию к внутренним RPC интерфейсам.
artptr86
21.08.2024 10:45В чём по-вашему принципиальная разница в требованиях? Кажется, что документирование внешних API не отменяет описание структур данных.
Oangai
21.08.2024 10:45для внутренних API разработчики обычно имеют доступ к коду, внутренней документации и собственно к коллегам которые это создавали. Это позволяет большую гибкость, формализация на таком уровне больше мешает. Для внешних ровно наоборот. Нужно и то и другое, просто большинство программистов эти вещи путают.
Oangai
21.08.2024 10:45+8проблема в том что 99% современных программистов не знают что такое контрактное программирование, никогда о нем не слышали, а про всякие эти "схемы" не понимают зачем они вообще сдались. Если плебс не дорос до такой музыки, то она и не прижилась.
eimrine
21.08.2024 10:45+3Интересно, разметка данных в стиле Lisp имеет право на жизнь? Из разделителей только скобки и пробельные символы, из типов данных только текст, из зарезервированных символов кроме вышеназванных только обратная кавычка. Поле phone_numbers->type я реализовал двумя способами, потому что и двоеточие - вполне валидный символ, и ещё один уровень иерархии - семантически правильный способ передать идею перечисления с использованием символа
-
.(person (name John Doe) (age 30) (email john.doe@example.com) (address (street 123 Main St) (city Anytown) (state CA) (zip 12345)) (phone_numbers (type:home (number 555-1234)) (type (work (number: 555-5678)))))
NeoCode
21.08.2024 10:45+5Вот питонятины не надо. Все эти пробелы для задания структуры ужасны. Вот представьте что нужно в один файл вставить кусок такого кода из другого файла... Или изменить структуру, перенести что-то на другой уровень вложенности...
XML слегка громоздок, но это вопрос его применения. Зачем все эти схемы, когда можно просто пользоваться тегами и атрибутами? И он максимально человекочитаем. Каждый тег имеет имя, и глядя на некоторую строчку в середине файла, сразу понятно что это за данные. А вообще корпорации любят наворачивать в свои файлы лишнего, но они и с любым другим форматом будут также наворачивать.
JSON имеет некоторые недостатки, но есть же JSON5. Все что нужно Сообществу - принять таки наконец этот формат в качестве основного.
CorwinH
21.08.2024 10:45+1есть же JSON5.
Сомневаюсь, что ConfigurationBuilder.AddJsonFile() умеет с ним работать (C#).
Ну и произвольное внешнее API тоже, скорее всего, не умеет.
Два частых случая использования выпадают.Сообществу - принять таки наконец этот формат в качестве основного.
Будем ждать. (
Revertis
21.08.2024 10:45+15мне этот формат не приглянулся и я никогда не использовал его в своих проектах
Дальше можно не читать.
Но предлагать вместо XML отвратный YAML, который придуман придурками для идиотов? Это совсем ужас-ужас.
despair Автор
21.08.2024 10:45Можете аргументировать?)
Revertis
21.08.2024 10:45+8Держите: https://habr.com/ru/articles/710414/
Не забудьте посмотреть рейтинг статьи.
ALexKud
21.08.2024 10:45+1Перевел в базу данных конфигурацию нескольких десятков приборов, которые были в xml описаны. Некоторые файлы больше 100 страниц. Файлы использовались некоей софтиной для настройки приборов. Правка этих файлов была тем еще квестом для программеров. Перевел все в таблицы SQL Server и SQLite не потеряв связи между таблицами. Это была очень нетривиальная задача. Сейчас новая программа работает с SQL базами. Новые конфигурации править и создавать неизмеримо проще стало.
saboteur_kiev
21.08.2024 10:45+6XML жил, жив и будет жить.
XML это не описание формата, это стандарт markup language, в рамках которого можно написать свой формат и он будет корректно распознан парсером.
yaml, который типа как human-friendly, должен быть удобен для редактирования руками. Да, когда нужно что-то поправить или перенести кусок текста - да. Но без дополнительного софта написать на ямле с нуля документ хотя бы размером в килобайт и не сделать кучи ошибок - кажется малореальнор.
А вот в xml вполне можно глазами отслеживать все зависимости и вложенности, и простой подсветки текстового редактора может быть достаточно, чтобы закрыть все теги, кавычки и написать корректный документ с первого раза.Вот вы пишете, что XML невозможно просто запаковать и распаковать между двумя языками XML. А что в другом формате это возможно без предварительного соглашения? Нет, нужно будет заранее разобраться с переменными, типами, аллоцировать место. При этом для XML даже существовал нормальный себе стандарт SOAP, который для этого и предназначен.
Просто каждую технологию следует использовать разумно. Приводя в пример адовый XML в одну строчку - это просто смешно.. Кто заставлял так делать? =)Если JSON удобнее для объектов, то XML удобнее для документов, и в этом плане они могут быть взаимозаменяемыми, но заметно же что специализация присутствует.
И для XML, как и для JSON работает универсальный xpath, то есть нет проблем с конвертированием, и избыточность XML может обернуться наоборот дополнительной гибкостью с использованием тегов и аттрибутами тегов.
Все три формата существуют потому что они не лучше друг друга, а каждый чуть удобнее в чем-то.Mingun
21.08.2024 10:45А что в другом формате это возможно без предварительного соглашения?
Все же что плохо и одновременно хорошо в XML -- это то, что там нет выделенного синтаксиса для коллекций. Чтобы сделать коллекцию, вы просто повторяете тег. Причем между тегами коллекции можете засунуть теги, к ней не относящиеся. А если у вас коллекция перечислений, как показанный выше
List<Figure>
... В общем, без схемы совершенно непонятно, как это разложить на поля и коллекции, придется все в одну коллекцию запихнуть. Для универсального узла данных (Value
) есть только 2 типа -- строка и мульти-мапа строк вValue
, что обычно все же маловато. В языках обычно нет такой гибкости и это создает сложности маппинга. Я поддерживаюquick-xml
и именно поэтому всякие serde-овские преобразования, использующие кеширование черезdeserialize_any
, не работают в XML. Тут конечно и сам дизайн serde виноват, можно было сделать лучше, но все же.Опять же, смешивание тегов коллекции с другими полями, или даже тегов разных коллекций, создает сложности парсинга. А если у вас 2 коллекции данных с разными тегами в каждой, то их в общем случае вообще невозможно разделить. У вас в типах обычно коллекции в разных полях лежат, а не вперемешку. И при десериализации обычно ожидается, что сначала прочтем полностью одно поле, затем полностью другое, на что полагаются всякие фреймворки, позволяя пользователю отдельно кастомизировать чтение каждого типа, компонуя десериализаторы. Чтобы это работало в XML, приходится кешировать на уровне десериализатора.
А хорошее при это то, что если у вас было поле скалярное и вы его делаете коллекцией -- то ваш XML никак не меняется и вы легко парсите предыдущие версии формата. Правда сдается мне, эта ситуация намного реже встречается, чем первая...
saboteur_kiev
21.08.2024 10:45+1нет выделенного синтаксиса для коллекций
Тогда если вам нужны коллекции, можно использовать JSON. Но автор статьи утверждает что XML вообще во всех отношениях хуже, в то время как есть огромное количество применений именно XML.
vvdev
21.08.2024 10:45+3Это сейчас всерьёз, про коллекции?
Хоть бы в спецификацию xsd кто заглянул, прежде чем... новаторствовать.
Предложенные варианты вообще ни в какие ворота, конечно, НО - они работают, если уж так прям нужно.
Mingun
21.08.2024 10:45Конечно всерьез, даже код написан. Мапить коллекции во фреймворках, не подумавших о специфике XML, хрупко и неэффективно.
И что вы ожидаете найти в спецификации XSD? А главное, откуда вы ее возьмете xsd для вашего xml, когда у вас на руках только сам документ, а XSD, в отличие от DTD, не встраивается (а даже если бы и встраивался, это все равно не охватит все случаи).
Предложенные варианты вообще ни в какие ворота, конечно, НО - они работают, если уж так прям нужно.
Предложенные варианты чего? У нас есть API сторонней библиотеки, которое ожидает что мы будем отдавать запрошенный тип для указанного поля, в том порядке, в котором она попросит. Какие еще варианты реализации вы бы предложили?
vvdev
21.08.2024 10:45+1Чтобы сделать коллекцию, вы просто повторяете тег.
И что вы ожидаете найти в спецификации XSD?
Ну, как ожидаю? Я находил. К примеру, можно найти как описываются повторящиеся элементы и из этого сделать вывод, как наиболее... разумно сериализовать коллекцию. К примеру - практически как в JSON, т.е.
<SomeInstance> ... <SomeCollectionProperty SomeCollectionAttribute="" AnotherAttribute=""> <SomeItem /> <SomeItem /> <SomeSubTypeItem /> </SomeCollectionProperty> ... </ SomeInstance>
Хотя, опять же, если вдруг разработчику схемы по каким-либо соображениям приспичило сериализовать так, как описано - нет проблем, будет работать. И даже валидную XSD для такого можно написать.
Предложенные варианты чего? У нас есть API сторонней библиотеки, которое ожидает что мы будем отдавать запрошенный тип для указанного поля, в том порядке, в котором она попросит. Какие еще варианты реализации вы бы предложили?
Так я не понял, это сторонняя библиотека требовала на вход такой XML?
Впрочем, не важно, удивление моё адресовано авторам новаторского подхода к сериализации пропертей-коллекций.
Но, повторю ещё раз: и так тоже можно, если очень надо. Просто неоднозначно и странно.
Несколько нелогично, по-моему, упоминать подобное как претензию к XML
inkelyad
21.08.2024 10:45Смысл вот в чем - если видишь тот XML, что показан (где очень удачно выбраны имена - явно написано, что это коллекция), но в виде
<SomeInstance> ... <PropertyName> <SomeItem /> <SomeSubTypeItem /> </PropertyName> ... </ SomeInstance>
То невозможно понять, SomeName - это коллекция с разными типами элементов, или это просто объект с двумя полями.
Ну да, если тебе схему дали, где указано, что SomeItem и SomeSybTypeItem может быть много - то это гораздо понятнее. Но непосредственно из синтаксиса XML-ки этого не видно.
vvdev
21.08.2024 10:45+1Ок, с этим не поспоришь.
Да, тут нужна схема или определение соответствующего типа на языке программирования - что на моём опыте в 99% случаев наличествует.
И вообще - при публикации XML API не публиковать схему - нехорошо.
...но возможно ;)
ZetaTetra
21.08.2024 10:45+8Для XML столько всего нагенерили и наавтоматизировали, что тут проще просто поизучать готовое, прежде чем выбирать как лучше передавать данные: binary, json, xml или другой подвид формата ключ-значение.
WSDL - (это из SOAP) используется для автоматической генерации сервера и клиента.
В результате при обновлении или выпуска новой версии пользователям просто рассылается письмо:Мы там новую версию выложили, переключитесь по возможности
Пользователь консьюмит ендпоинт и автоматом (если среда позволяет) получает полное описание всех ендпоинтов и payload'а с типами данных.
Т.е. по существу, пользователю может быть всё равно в каком формате написан диалог.
Что-то по аналогии с gRPC только с более жирным и читаемым payload'ом.Чтобы понимать гибкость, M$ написали универсального клиента для SOAP, который при обработке WSDL сразу генерит таблицу с полями и типами данных на лету (Внутри этого клиента - вызов консольного приложения).
XPath (+XQuery) - позволяет с лёгкостью выполнять query запросы к документу.
Для примера, если нам надо получить массив узлов из документа где в узле атрибут равен определённому значению. Пару примеров:/bookstore/book[price>35]/title
for $x in doc("books.xml")/bookstore/book where $x/price>30 order by $x/title return $x/title
XSLT - Возможность навесить любое форматирование на XML документ.
Надо нам превратить сгенерённый XML с описанием кода в HTML? - не проблема.<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="artist"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
XSD - валидация XML документа перед процессингом.
Какие атрибуты могут быть в таком узле, какое количество дочерних узлов может быть в родительсом узле и т.п.
К примеру используется в .config файлах для .NET Framework проектов, где через intellisence рисует где будет ошибка, куда можно добавить какой атрибут или узел. К примеру:<xs:element name="shipto"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="address" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
По поводу компактности, тоже спорно, ибо можно использовать атрибуты которых нет в JSON. Для и попроще если приходится имет дело с HTML 5 (Или 4.x Strict). Для примера:
<Books> <Book Title="First book" Author="First book author" /> <Book Title="Second book" Author="Second book author" /> </Books>
{ "Books": [ {"Title":"First book","Author":"First book author"}, {"Title":"Second book","Author":"Second book author"} ] }
Это я к тому, что XML - это более сложный формат для работы со структурированными данными, в отличии от JSON.
И как писали в отказе на добавление стандарта, по аналогии на WSDL, для JSON на w3.org:
Не превращайте JSON в XML. Это 2 разных формата для разных нужд.
inkelyad
21.08.2024 10:45XSLT - Возможность навесить любое форматирование на XML документ.
Вот только во всех случаях, кроме тривиальных приходится серьезно вспоминать функциональное программирование и разное pattern matching. И в результате полученное преобразование, по сути - write only. Подавляющему большинству разработчиков, кроме тех, которые эти xslt на постоянной основе пишут - легче xml в основной язык втянуть и там уже нужным способом все отформатировать.
ZetaTetra
21.08.2024 10:45Зависит от задачи, для примера если мы пишем что-то типа Sandcastle, когда мы можем поправить output как нам удобно, то писать что-то самописное для преобразования будет совсем не круто.
ImagineTables
21.08.2024 10:45+2Сравним ЭТО, например, с YAML, где сами правила форматирования (как и в Python, например), делают просто невозможным превращение документа в нечитаемый треш
Мне как-то неуютно от мысли, что зато форматирование может исказить смысл данных.
Ваш однострочный пример я скопировал в студию, нажал Format, и знаю, что при этом точно ничего не сломалось. Кстати, сразу стало видно, что у вас там последний тег не закрыт.
Я не фанат XML, но и особой ненависти к нему не питаю.
misha_ruchk0
21.08.2024 10:45+2" XML, который мы так любим, был придуман ещё в конце 1990-х ..."
Хмм.. C must die first! C, который мы тоже любим, придумали задолго до XML.
SquareRootOfZero
21.08.2024 10:45С "чудовищной избыточностью" и "человекочитаемостью" в кавычках всё так, за остальные пункты сказать не могу. Всякий софт, бывало, сохраняет данные в собственном бинарном формате (единицы килобайт), в текстовом а-ля CSV (десятки килобайт), и в XML (хоба, десятки мегабайт, как с куста). При том что человекочитаемость не нужна изначально. А где же она нужна и как там поможет XML? Ну вот в каких-то небольших конфигах нужна, там, в принципе, не так страшен XML, хотя для небольших конфигов ничуть не хуже подошло бы буквально что угодно, хоть INI-файлы, хоть S-expressions, а на больших конфигах этот XML превращается в такой адский суп из тэгов, что всё равно нереально там чего-то человекочитать. Обычно когда с джавистами приходится взаимодействовать, у них у всех XML головного мозга, повбывав бы, даже не из злобы, а из милосердия...
trewsa
21.08.2024 10:45+4Вся мощь XML это xmlschema и xml transform, ни в одном из форматов нет подобного даже и близко.
CorwinH
Это легко решается плагином к любимому текстовому редактору.
Постепенно JSON приходит на смену XML (обмен данными с API, файлы конфигурации). А если бы в нём можно было комментарии писать, то было бы совсем хорошо.
yarkov
Та вроде не запрещает никто ))
Khanik
У JSON есть минусы в том, каким образом он хранится. JSON, что в POSTGRES, что например в библиотеке QT всегда отсортирован. Положил в JSONB в одном виде, достаёшь а там всё не так, как ты ложил. Например ты сериализуешь музыкальные альбомы, которые ты в своём списке положил в определённом порядке, сериализовал, десиарелизовал, а там всё в алфавитном порядке (или ещё каком-то другом). Приходится заводить поля, чтобы хранить порядок и потом отсортировывать. С XML всё не так, как положил, так и взял.
ggo
Строго говоря, XML тоже не всегда читается из clob поля в том же виде что и был при записи. Когда это принципиально важно, приходится писать в blob.
А если используется blob, то и json туда же можно писать.
Да, postgres не сможет из такого поля условия применять. Но, как всегда, приходится выбирать....
kozlyuk
Порядок элементов в списках не меняется при сериализации и десериализации. Порядок ключей в объекте действительно не определен. Но тут уже вопрос к библиотеке, которая занимается сериализацией, почему она представляет упорядоченный словарь как объект, а не как список пар (например,
OrderedDict
в Python этим грешит).