Как проверить правильность XML в Ruby?
Очевидно, мне нужно (а) преобразовать обе строки в канонический XML или (b) сравнить их синтаксические деревья. Следующее не работает, потому что возвращенный объект документа не имеет разумного ==
.
Nokogiri.XML(doc_a) == Nokogiri.XML(doc_b)
И не делает следующее, потому что Nokogiri to_xml
оставляет некоторые внутренние пробелы:
Nokogiri.XML(doc_a).to_xml == Nokogiri.XML(doc_b).to_xml
Это разумное приближение равенства (и будет работать в большинстве случаев), но это не совсем верно:
Nokogiri.XML(doc_a).to_xml.squeeze(' ') == Nokogiri.XML(doc_b).to_xml.squeeze(' ')
Я уже использую Nokogiri, поэтому я бы предпочел придерживаться его, но я буду использовать любую библиотеку.
Ответы
Ответ 1
Если вы ищете структурное равенство и не заботитесь о порядке тегов и атрибутов, возможно, библиотека xml-simple - это хороший выбор. Он преобразует xml в структуры данных ruby (хэши и списки), которые можно безопасно сравнить с оператором ==
.
Ответ 2
На самом деле существует пара хороших библиотек на основе Nokogiri для проверки эквивалентности деревьев XML, включая equivalent-xml или nokogiri-diff, что может быть полезно.
Я предпочитаю эквивалент-xml, потому что он обеспечивает немного большую гибкость (возможно, за счет строгости?), позволяя сравнивать или без учета порядка элементов или пробелов.
Ответ 3
Преобразование их в строки не будет очень успешным. Например, если элемент имеет два атрибута, действительно ли порядок имеет значение? В большинстве случаев нет. Имеет ли порядок детей данного node? Зависит от того, что вы делаете. Но если ответ на один из этих вопросов "нет", то простое сравнение строк в лучшем случае является kludge.
В Нокигири нет ничего, чтобы сделать это за вас; вам придется строить его самостоятельно. Аарон Паттерсон обсуждает некоторые проблемы здесь:
Что касается документа XML что два узла никогда не были равны. Каждый node в документе другой. У каждого node много атрибуты для сравнения:
- Является ли имя тем же самым?
- Как насчет атрибутов?
- Как насчет пространства имен?
- Как насчет числа детей?
- Все ли дети одинаковы?
- Является ли он родительским node тем же?
- Что относительно позиции по отношению к родственным узлам?
Подумайте о добавлении двух узлов в тот же документ. Они никогда не могут то же положение относительно родного брата узлов, поэтому два узла в документ не может быть "равным".
Однако вы можете сравнить два различные документы. Но вам нужно ответьте на эти 7 вопросов вы идете по двум деревьям. Ваш требования к одинаковости могут отличаться от других.
Это лучший выбор: прогуляйтесь по деревьям и сравните их.