Что нужно, чтобы получить «LyricArtist» из этого XML-канала с помощью Nokogiri? - PullRequest
0 голосов
/ 14 июня 2010

Сначала xml: http://api.chartlyrics.com/apiv1.asmx//GetLyric?lyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e

doc = Nokogiri::XML(open("http://api.chartlyrics.com/apiv1.asmx//GetLyric?lyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e"))

Успешно получит содержимое документа.

После этого момента я не могу войти внутрь и получить данные, и я не уверен, почему?

Например, я бы ожидал:

doc.xpath("//LyricArtist")

Чтобы отбросить художника, но это не так.

Я пробовал то же самое с другими каналами, напримеркак RSS-канал по умолчанию, который предоставляет любая установка WordPress, и если я делаю что-то вроде:

doc.xpath("//link")

, я получаю список всех «ссылок».

Я определенно что-то упускаю и буду рад вашему вкладу.спасибо !!

Ответы [ 2 ]

3 голосов
/ 14 июня 2010

Элементы XML соответствуют пространству имен и привязаны к http://api.chartlyrics.com/.

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

<GetLyricResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://api.chartlyrics.com/">

Чтобы сопоставить элемент, связанный с пространством имен, вам нужно либо объявитьпрефикс пространства имен, связанный с этим URI, и используйте этот префикс пространства имен в выражении XPATH, либо используйте выражение XPATH, которое либо игнорирует пространства имен, либо совпадает по-разному.

Вы можете сопоставить элементы, а затем использовать local-name() для сопоставленияимя элемента, независимо от объявленного пространства имен.

//*[local-name()='LyricArtist']

Если вы хотите быть более точным, вы можете использовать local-name() для соответствия имени элемента и namespace-uri() для соответствия объявленному пространству имен.

//*[local-name()='LyricArtist' and namespace-uri()='http://api.chartlyrics.com/']

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

0 голосов
/ 14 июня 2010

Ему не нравится что-то в пространстве имен или схеме.

uri = "http://api.chartlyrics.com/apiv1.asmx//GetLyric?LyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e"
x = open(uri).read()
x = x.sub(/<.*?>/,'').sub(/<.*?>/,'<GetLyricResult>')
doc = Nokogiri::XML(x)
puts doc.xpath('//LyricArtist').text()
...