#javascript #xmldom
#javascript #xmldom
Вопрос:
У меня есть js-скрипт, который считывает и анализирует XML. Он получает XML из запроса XMLHttpRequest (который связывается со скриптом php, который возвращает XML). Предполагается, что скрипт получит 2 или более узлов под первым родительским узлом. У двух узлов, которые для этого требуются, имя четко определено, у остальных может быть любое имя. Вывод из php может быть:
<?xml version='1.0'?>
<things>
<carpet>
<id>1</id>
<name>1</name>
<desc>1.5</desc>
</carpet>
<carpet>
<id>2</id>
<name>2</name>
<height>unknown</height>
</carpet>
</things>
Здесь все ковры имеют 7 узлов.
но это также может быть:
<?xml version='1.0'?>
<things>
<carpet>
<id>1</id>
<name>1</name>
<desc>1.5</desc>
</carpet>
<carpet><id>2</id><name>2</name><height>unknown</height></carpet>
</things>
Здесь первый ковер имеет 7 узлов, второй ковер имеет 3 узла.
Я хочу, чтобы мой код javascript обрабатывал оба точно так же быстрым и чистым способом.
Если возможно, я бы хотел удалить все текстовые узлы между каждым тегом. Таким образом, код, подобный приведенному выше, всегда будет обрабатываться как:
<?xml version='1.0'?>
<things><carpet><id>1</id><name>1</name><desc>1.5</desc></carpet><carpet><id>2</id><name>2</name><height>unknown</height></carpet></things>
Возможно ли это быстрым и эффективным способом? Я бы хотел не использовать какую-либо функцию get (getElementsByTagName(), getElementById, …), если это возможно и если это более эффективно.
Ответ №1:
Довольно просто обойти DOM и удалить узлы, которые вы считаете пустыми (содержащими только пробелы).
Это непроверенное (протестировано и исправлено, живая копия здесь), но это выглядело бы примерно так (замените эти магические числа символами, очевидно):
var reBlank = /^s*$/;
function walk(node) {
var child, next;
switch (node.nodeType) {
case 3: // Text node
if (reBlank.test(node.nodeValue)) {
node.parentNode.removeChild(node);
}
break;
case 1: // Element node
case 9: // Document node
child = node.firstChild;
while (child) {
next = child.nextSibling;
walk(child);
child = next;
}
break;
}
}
walk(xmlDoc); // Where xmlDoc is your XML document instance
Там мое определение «пустого» — это все, что имеет пробелы только в соответствии с пониманием интерпретатора JavaScript s
(пробел) Класс регулярных выражений. Обратите внимание, что некоторые реализации имеют проблемы с s
недостаточным включением (несколько «пустых» символов Unicode за пределами диапазона ASCII не совпадают и т.д.), Поэтому обязательно протестируйте с вашими образцами данных.
Комментарии:
1. Я не буду использовать ваше предложение, но вы дали мне идею, которая мне нужна, чтобы сделать шаг вперед, которого достаточно для решения этой проблемы, спасибо.
2. @brunoais: Хорошая сделка, рад, что помогло.
3. @brunoais Не хотите поделиться своим собственным решением / что вы в итоге сделали? Просто ради интереса.
Ответ №2:
Я бы просто попробовал очень грубую замену строки: предполагая, что вы сохраняете это в переменной с именем xml
:
var rex = /(<(/)?[A-Za-z0-9] >)(s) /gi;
var a = xml.replace( rex, "$1" );
вот полный тест, который я собрал:
<html><head></head>
<body>
<script type="text/javascript">
var xml = "<?xml version='1.0'?>n"
"<things>n"
" <carpet>n"
" <id>1</id>n"
" <name>1</name>n"
" <desc>1.5</desc>n"
" </carpet>n"
" <carpet>n"
" <id>2</id>n"
" <name>2</name>n"
" <height>unknown</height>n"
" </carpet>n"
"</things>";
var rex = /(<(/)?[A-Za-z0-9] >)(s) /gi;
var a = xml.replace( rex, "$1" );
alert( a );
</script>
</body></html>
Комментарии:
1. @Liv ваше решение использует регулярное выражение, которое является средним или медленным способом решения. Кроме того, вы предполагаете, что я получаю текст с сервера, что неверно, я получаю объект XML. Извините, но ваше решение не является решением.
2. ваш XMLHttpRequest позволяет вам извлекать ответ в виде текста через его свойство
responseText
. Кроме того, обработка регулярных выражений выполняется не медленно — это заблуждение; вы обнаружите, что на самом деле это намного быстрее, чем написание собственного кода для выполнения поиска и замены в строке; более того, это определенно быстрее, чем обход DOM! Но я принимаю тот факт, что вы не хотите использовать регулярные выражения и предпочитаете методы только DOM.3. Использование регулярных выражений для изменения разметки XML или HTML в масштабе макроса, как правило, работает не очень хорошо.
4. @T.J. Crowder : Прошу, уточните!
5. Я слышал вас — regex не подходит для синтаксического анализа XML В целом. Однако, учитывая XML, описанный в приведенном выше вопросе, когда нет атрибутов и т.д., регулярное выражение будет работать. Другими словами, я ответил на ЭТОТ вопрос не на общий вопрос о разборе XML с использованием регулярных выражений. (И да, я согласен с вашей точкой зрения, что регулярное выражение — неправильный способ анализа XML!)