Как заставить мой виджет не падать, если в узле xml нет значения?
Я получаю XML-файл и хочу получить данные из него. Источник xml на самом деле не имеет значения, но я должен получить определенное поле:
tracks = xmlDoc.getElementsByTagName("track");
variable = tracks.item(i).childNodes.item(4).childNodes.item(0).nodeValue;
Теперь это работает как талисман, за исключением случаев, когда в узле нет значения. Итак, если структура такая:
<xml>
<one>
<two>nodeValue</two>
</one>
<one>
<two></two>
</one>
</xml>
виджет рухнет на втором узле 'one', потому что в узле 'two' нет значения. Консоль говорит:
TypeError: tracks.item(i).childNodes.item(4).childNodes.item(0) has no properties
Любые идеи о том, как заставить виджет просто видеть пустой как пустую строку (ноль, пустой или ""), а не сбой? Я предполагаю, что-то в соответствии с данными, getValue (), текст или что-то еще.
с помощью
var track= xmlDoc.getElementsByTagName('track')[0];
var info= track.getElementsByTagName('artist')[0];
var value= info.firstChild? info.firstChild.data : '';
не работает и возвращает "TypeError: track не имеет свойств". Это со второй строки, где художник называется.
3 ответа
Yahoo! Виджеты не реализуют все основные функции JavaScript, необходимые для использования кода браузера в виджете.
Вместо того, чтобы использовать:
tracks = xmlDoc.getElementsByTagName("track");
variable = tracks.item(i).childNodes.item(4).childNodes.item(0).nodeValue;
для получения значений лучше использовать Xpath с прямым преобразованием в строку. Когда строка пуста в Yahoo! Виджеты не дают никаких ошибок, но возвращают "пусто". innerText и textContent (основной способ javascript в браузерах, используемый вместе с такими вещами, как getElementsByTagName), не полностью (или вообще не) реализованы в Yahoo! Движок виджетов и заставить его работать медленнее и довольно ужасно реагировать на xmlNodes и childNodes. Однако простой способ просмотреть структуру XML-документа заключается в использовании "оценки" для получения всего необходимого (включая списки узлов) из XML-документа.
Узнав об этом, я решил сделать все намного проще и менее чувствительным к сбоям и ошибкам. Также я решил поместить объекты в массив, чтобы облегчить работу с ними.
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;
}
Проверьте, что у узла 'two' есть дочерний узел, прежде чем получить доступ к его данным.
childNodes.item (i) (или простую форму JavaScript childNodes[i]), как правило, следует избегать, так как он немного хрупок, полагаясь на то, что текстовые узлы пробелов находятся в точно ожидаемом месте.
Я бы сделал что-то вроде:
var tracks= xmlDoc.getElementsByTagName('track')[0];
var track= tracks.getElementsByTagName('one')[0];
var info= track.getElementsByTagName('two')[0];
var value= info.firstChild? info.firstChild.data : '';
(Если вы заранее не знаете тэги 'one' и 'two', вы всегда можете использовать 'getElementsByTagName('*')', чтобы получить все элементы, если вам не нужна поддержка IE5, где это не работает.)
Альтернативой последней строке является использование метода для чтения всего текста внутри узла, включая любые его дочерние узлы. Это не имеет значения, если узел содержит только один текстовый узел, но может быть полезно, если дерево может быть денормализовано или содержать EntityReferences или вложенные элементы. Исторически сложилось так, что для получения этой информации нужно было написать метод recurse, но в настоящее время большинство браузеров поддерживают свойство textContent DOM уровня 3 и / или расширение innerText в IE:
var value= info.textContent!==undefined? info.textContent : info.innerText;
Без dtd, которое позволяет одному элементу содержать два пустых элемента, вам придется анализировать и перебирать текст вашего xml, чтобы получить из него документ.
Пустые элементы подобны нулевым значениям в базах данных - помещаются во что-то, значение "Nothing" или "0", неразрывный пробел, что-либо вообще - или не включают два элемента.
Может быть, это может быть атрибут одного, а не элемент сам по себе. Атрибуты могут иметь пустые строки для значений. Лучше, чем призрачные элементы.