#ruby #xml #parsing #nokogiri
#ruby #xml #синтаксический анализ #nokogiri
Вопрос:
str = "<?xml version='1.0' encoding='utf-8'?><url>https://somehost?p1=v1amp;p2=v2</url>"
=> "<?xml version='1.0' encoding='utf-8'?><url>https://somehost?p1=v1amp;p2=v2</url>"
x = Nokogiri::XML(str)
=> #<Nokogiri::XML::Document:0x3fcaa893b900 name="document" children=[#<Nokogiri::XML::Element:0x3fcaa893b644 name="url" children=[#<Nokogiri::XML::Text:0x3fcaa893b48c "https://somehost?p1=v1=v2">]>]>
Почему удален ‘amp;p2’? после синтаксического анализа?
Ответ №1:
Это потому, что в контексте XML / HTML amp;
имеет особое значение. Вы должны избежать этого:
<?xml version='1.0' encoding='utf-8'?><url>https://somehost?p1=v1amp;amp;p2=v2</url>
Он анализирует его как объект amp;p2
, который не является допустимым объектом, поэтому он удаляется, оставляя вас с p1=v1=p2
Комментарии:
1. Я уверен, что это правильное объяснение, хотя теоретически W3C-совместимому анализатору XML не разрешается пытаться восстановить синтаксические ошибки таким образом, он должен сообщить об ошибке и остановиться.
2. @MichaelKay Если у вас здесь есть обращение, напишите отчет об ошибке.
3. Если вы думаете, что я собираюсь установить программное обеспечение, которым я никогда не пользовался, ознакомиться с ним и запустить тест только для того, чтобы отправить отчет об ошибке, то у вас странное представление о моих жизненных приоритетах. В любом случае, я понятия не имею, ошибка ли это. Это может быть преднамеренное и документированное несоответствие. В конце концов, нет закона, требующего соответствия W3C.
4. Nokogiri чем-то похож на щенка в том, что он попытается вернуть что-то полезное, что хорошо при попытке выполнить много пакетной обработки. Недостатком этого является то, что HTML или XML могут быть искажены при попытке восстановления после неправильного ввода. Помогает
errors
метод, который при использовании в документе OPs сообщает нам о проблеме:# => [#<Nokogiri::XML::SyntaxError: 1:69: FATAL: EntityRef: expecting ';'>]
другими словами, он думал, чтоamp;p2
это объект, и ничего не мог с ним сделать. Программист должен воспользоваться этим и отреагировать соответствующим образом. Еслиerrors
возвращает пустой список, все в порядке.