Разные результаты между запросами xpath и css

#nokogiri

#nokogiri

Вопрос:

Я изучаю Nokogiri и столкнулся с запутанными проблемами, по которым я был бы признателен за чье-либо мнение. ПРИМЕЧАНИЕ: Я также довольно новичок в Ruby, поэтому ожидаю, что сделал что-то действительно безумное. Прошу прощения, если это так.

У меня есть простой тест, который сравнивает результаты запроса XPath и запроса CSS в XML-документе. Запрос CSS работает, а XPath — нет, и я затрудняюсь объяснить, почему.

   should "get same result from Nokogiri using XPath or CSS syntax" do

    xml_source = "<?xml version="1.0" encoding="utf-8"?><accounts xmlns="http://api.esendex.com/ns/"><account id="2b4a326c-41de-4a57-a577-c7d742dc145c" uri="http://api.esendex.com/v1.0/accounts/2b4a326c-41de-4a57-a577-c7d742dc145c"><messagesremaining>100</messagesremaining></account></accounts>"

    ndoc = Nokogiri::XML(xml_source)

    node_value = ndoc.css("accounts account messagesremaining").count
    assert_equal 1, node_value

    node_value = ndoc.xpath("//accounts//account//messagesremaining").count
    assert_equal 1, node_value

  end
  

Второе утверждение завершается ошибкой с node_value, равным нулю.

Заранее спасибо.

Ответ №1:

У вас две проблемы.

Сначала xpath должен быть «//учетные записи/account/messagesremaining».

Во-вторых, у вас есть пространство имен по умолчанию «http://api …». Вам необходимо указать пространство имен каждого элемента при выполнении запроса xpath (запросы css игнорируют пространство имен).

Извините, я не знаю Nokogiri, но у меня есть документация о том, как использовать пространства имен в запросах xpath.

Комментарии:

1. Спасибо, Ричард, пространство имен было ключевой проблемой. Я не рассматривал это, потому что это было по умолчанию. Виноват. XPath сработал, когда я добавил ссылки на пространство имен, потому что я избегал косых черт при использовании строки, заключенной в кавычки. Хотя удвоение в начале для обозначения корня, я знаю, делает это более эффективным. node_value = ndoc.xpath('//api:accounts/api:account/api:messagesremaining', 'api' => 'http://api.esendex.com/ns/').count

2. «У меня есть документация о том, как использовать пространства имен в запросах xpath». У Nokogiri есть документация о том, как с ними работать. Преимущество CSS в том, что оно автоматически применяет xmlns пространство имен.