DOM навигация: устранение текстовых узлов - PullRequest
3 голосов
/ 28 апреля 2011

У меня есть скрипт js, который читает и анализирует XML. Он получает XML из запроса XMLHttpRequest (который связывается со скриптом php, который возвращает XML). Предполагается, что скрипт получит 2 или более узлов под первым parentNode. Два необходимых ему узла имеют четко определенное имя, остальные могут быть любыми. Вывод из 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, ...), если это возможно и если это более эффективно.

Ответы [ 2 ]

6 голосов
/ 28 апреля 2011

Довольно просто пройтись по 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 (пробел) RegExp. Обратите внимание, что в некоторых реализациях есть проблемы с тем, что \s недостаточно инклюзивен (несколько «пустых» символов Unicode за пределами диапазона ASCII не сопоставляются и т. Д.), Поэтому обязательно протестируйте данные примера.

0 голосов
/ 28 апреля 2011

Я бы просто попробовал заменить очень грубую строку: предполагая, что вы храните ее в переменной с именем 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>
...