Как использовать Xpath в Yahoo! Виджеты для обхода дерева?

Я создаю сайт Yahoo! Widget и делал это раньше без проблем (создание виджета). Я получаю xml-документ через веб-ссылку и хочу, чтобы все узлы входили в дерево. Я делаю это:

var request = new XMLHttpRequest();
        request.open( "GET", url, false );
        request.send();
        if ( request.status == 200 )
        {
            doc = request.responseXML;
            tree = doc.evaluate("/lfm");
            status = tree.item(0).getAttribute("status")
            if(status == "ok")
            {
                print ("status is ok!");
                tracks = doc.evaluate("/lfm/recenttracks[1]/track");
                for(i=0;i<tracks.length;i++)
                {
                    artist = tracks.item(i).firstChild.firstChild.data;
                }
            }
        }
    }

Таким образом вы можете вывести узел artist из дерева. однако есть проблема, если вы хотите иметь следующего родного брата. Вы должны позвонить

tracks.item(i).firstChild.nextSibling.firstChild.data;
tracks.item(i).firstChild.nextSibling.nextSibling.firstChild.data;
tracks.item(i).firstChild.nextSibling.nextSibling.nextSibling.firstChild.data;

чтобы сделать это. Узел рядом с этим добавляет к нему 'nextsibling' и так далее. Я не хочу продолжать добавлять эти узлы и подумал, что можно будет использовать childNodes[i] следующим образом:

artist = tracks.item(i).childNodes[0].firstChild.data;
nextitem = tracks.item(i).childNodes[1].firstChild.data;

это не работает, хотя. он возвращает "childNodes[0] не имеет свойств" независимо от того, как я его использую. Теперь я думаю, что в Xpath есть способ сделать это в цикле for:

name = doc.evaluate("string(/lfm/recenttracks[1]/track["+i+"]/name)");
                    print(name);
othernode = doc.evaluate("string(/lfm/recenttracks[1]/track["+i+"]/album)");
                    print(othernode);

а затем увеличивая i для следующего трека. но каким-то образом это возвращает только один элемент. он не извлекает больше элементов в цикле for. i-1 тоже не работает.

Кто-нибудь знает, как использовать выражение Xpath с моим значением i, чтобы выбрать узел, а затем получить подузлы для каждого суперузла? Для каждой дорожки я хочу получить исполнителя, имя, возможность потоковой передачи, mbid, альбом, URL-адрес, изображение (маленькое), изображение (среднее), изображение (большое) и дата.

мой xml-файл выглядит так:

<lfm status="ok">
   <recenttracks user="xaddict">
      <track nowplaying="true"> 
         <artist mbid="f5b8ea5f-c269-45dd-9936-1fedf3c56851">The Presets</artist>
         <name>Girl (You Chew My Mind Up)</name>
         <streamable>1</streamable>
         <mbid></mbid>
         <album mbid="b150d099-b0f3-4feb-9a05-34e693c6dd24">Beams</album>
         <url>http://www.last.fm/music/The+Presets/_/Girl+%28You+Chew+My+Mind+Up%29</url>
         <image size="small">http://userserve-ak.last.fm/serve/34s/8696437.jpg</image>
         <image size="medium">http://userserve-ak.last.fm/serve/64s/8696437.jpg</image>
         <image size="large">http://userserve-ak.last.fm/serve/126/8696437.jpg</image>
         <date uts="1236440600">7 Mar 2009, 15:43</date>
      </track>
      <track > 
         <artist mbid="f5b8ea5f-c269-45dd-9936-1fedf3c56851">The Presets</artist>
         <name>Get Outta Here</name>
         <streamable>1</streamable>
         <mbid></mbid>
         <album mbid="0469956f-d895-4120-8ec5-29ad41b9e2fd">Blow Up</album>
         <url>http://www.last.fm/music/The+Presets/_/Get+Outta+Here</url>
         <image size="small">http://userserve-ak.last.fm/serve/34s/20923179.png</image>
         <image size="medium">http://userserve-ak.last.fm/serve/64s/20923179.png</image>
         <image size="large">http://userserve-ak.last.fm/serve/126/20923179.png</image>
         <date uts="1236440242">7 Mar 2009, 15:37</date>
      </track>
   </recenttracks>
</lfm>

person xaddict    schedule 07.03.2009    source источник
comment
пример вашего исходного xml и того, что вы хотите получить от него, поможет.   -  person ax.    schedule 07.03.2009
comment
сделано, смотрите добавленный xml!   -  person xaddict    schedule 07.03.2009
comment
и, опять же, что вы хотите получить от этого?   -  person ax.    schedule 07.03.2009


Ответы (3)


Попробуй это

 for (var i = 0; i < xmlDoc.getElementsByTagName('track').length; i++)
            {
                alert(xmlDoc.getElementsByTagName('track')[i].getElementsByTagName('name')[0].childNodes[0].nodeValue); 
            }

если вы хотите использовать xpath, вы также можете попробовать следующее решение.

var s = xmlDoc.evaluate( '//track' ,xmlDoc, null, XPathResult.ANY_TYPE, null );
var track = s.iterateNext();

while (track)
{
     alert(track.getElementsByTagName('name')[0].textContent );
     track = s.iterateNext();
}
person gk.    schedule 07.03.2009
comment
Я хочу использовать XPath, так как он работает намного быстрее в Yahoo! Виджеты. Так что это не совсем вариант. Спасибо, в любом случае! - person xaddict; 07.03.2009
comment
Хорошо, попробуйте начальное значение 1 для индекса xpath. - person gk.; 08.03.2009
comment
Я попробовал это только сейчас, и кажется, что оба кода работают в обычном javascript, но первый возвращает TypeError: xmlDoc.getElementsByTagName(track)[0] не имеет свойств в Yahoo! Виджеты. Вторая функция возвращает s.iterateNext не существует - person xaddict; 23.03.2009
comment
Не могли бы вы опубликовать более подробную информацию о виджете Yahoo. А также вы уверены, что пытаетесь это сделать с объектом типа Xml, а не с любым пользовательским типом Yahoo. - person gk.; 23.03.2009

Можете ли вы опубликовать соответствующий фрагмент XML? Мы смотрим на ваш код, который его анализирует, но если бы у нас был сам XML, было бы проще обработать запрос Xpath. Наиболее полезным будет бит, содержащий такие элементы, как

<lfm>
    <recenttracks>
        <track>
            <album>

так далее

person Cheeso    schedule 07.03.2009

способ сделать это с полной поддержкой Xpath — использовать преобразование строк в Xpath. Я уже разместил этот код как ответ на другой вопрос и сделаю это снова. Я очень рад, что узнал об этом способе ведения дел.

var entries = xmlDoc.evaluate("lfm/recenttracks/track");
var length = entries.length;
for(var i = 0; i &lt; length; i++) {
   var entry = entries.item(i);
   var obj = {
      artist: entry.evaluate("string(artist)"),
      name: entry.evaluate("string(name)"),
      url: entry.evaluate("string(url)"),
      image: entry.evaluate("string(image[@size='medium'])")
   };
posts[i] = obj;
}
person xaddict    schedule 27.03.2009