Как заставить мой виджет не падать, если в узле xml нет значения? - PullRequest
1 голос
/ 23 марта 2009

Я получаю 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

Любые идеи о том, как заставить виджет просто видеть пустой как пустую строку (ноль, пустой или ""), а не сбой? Я предполагаю что-то вроде data , getValue () , text или что-то еще.

с помощью

var track= xmlDoc.getElementsByTagName('track')[0];
var info= track.getElementsByTagName('artist')[0];
var value= info.firstChild? info.firstChild.data : '';

не работает и возвращает «TypeError: дорожка не имеет свойств». Это со второй строки, где художник называется.

Ответы [ 3 ]

1 голос
/ 23 марта 2009

Проверьте, что у узла '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;
0 голосов
/ 27 марта 2009

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 &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;
            }
0 голосов
/ 23 марта 2009

без dtd, которое позволяет элементу one содержать пустой элемент two , вам придется анализировать и обрабатывать текст вашего xml, чтобы получить из него документ.

Пустые элементы подобны нулевым значениям в базах данных - помещаются во что-то, значение «Nothing» или «0», неразрывный пробел, что-либо вообще - или не включают элемент two .

Возможно, это может быть атрибут из one вместо отдельного элемента. Атрибуты могут иметь пустые строки для значений. Лучше, чем призрачные элементы.

...