Como usar XPath no Yahoo! Widgets para percorrer uma árvore?
-
05-07-2019 - |
Pergunta
Estou criando um Yahoo! Widget e ter feito isso antes, sem qualquer problema (criando um widget). Estou recebendo um documento xml através de um URL e deseja obter todos os nós de introdução de uma árvore. Eu estou fazendo isso:
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;
}
}
}
}
Desta forma, você pode obter o nó artista ??strong> para fora do árvore . há um problema mas se você quiser ter o próximo irmão . Você tem que chamar
tracks.item(i).firstChild.nextSibling.firstChild.data;
tracks.item(i).firstChild.nextSibling.nextSibling.firstChild.data;
tracks.item(i).firstChild.nextSibling.nextSibling.nextSibling.firstChild.data;
para obter este feito. O nó ao lado que adiciona um 'nextSibling' para ele e assim por diante. Eu não quero continuar a adicionar esses nós e pensei que seria possível usar childNodes [i] como este:
artist = tracks.item(i).childNodes[0].firstChild.data;
nextitem = tracks.item(i).childNodes[1].firstChild.data;
isso não funciona embora. ele retorna "childNodes [0] não tem propriedades" de qualquer maneira que eu usá-lo. Agora eu acho que há também uma forma de XPath para fazer isso em um loop 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);
e, em seguida, aumentando i para a faixa seguinte. mas de alguma forma isso retorna somente um item. ele não recuperar mais itens de um para -loop. i-1 não quer trabalhar.
Qualquer um sabe como usar uma expressão XPath com meu valor i para escolher um nó e, em seguida, obter os subnós por supernode? Por trilha Quero chegar artista, nome, streamable, mbid, álbum, url, imagem (pequena), imagem (médio), imagem (grande) e data.
meus xml aparência de arquivo como este:
<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>
Solução 3
o caminho totalmente XPath habilitado de fazer isso é usando a conversão corda em XPath. Ive já postou este código como uma resposta a outra pergunta e vai fazer isso de novo. Estou muito feliz que eu descobri sobre esta maneira de fazer as coisas.
var entries = xmlDoc.evaluate("lfm/recenttracks/track");
var length = entries.length;
for(var i = 0; i < 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;
}
Outras dicas
Tente este
for (var i = 0; i < xmlDoc.getElementsByTagName('track').length; i++)
{
alert(xmlDoc.getElementsByTagName('track')[i].getElementsByTagName('name')[0].childNodes[0].nodeValue);
}
Se você quiser usar XPath, você também pode tentar o abaixo solução.
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();
}
Você pode postar o fragmento XML relevante? Nós estamos olhando para o código que analisa-lo, mas se tivéssemos o XML em si, seria mais fácil contras até uma consulta XPath. Mais útil seria o pouco que tem elementos como
<lfm>
<recenttracks>
<track>
<album>
etc