1 (изменено: mozers, 2012-01-22 14:55:40)

Тема: HTA: XML Viewer

Разрешите представить вниманию простенький и наглядный вьюер для XML файлов.
Не думаю что он восхитит специалиста, поскольку в сети имеются более серьезные инструменты.
Но для "тетенек", выгружающих из своих программ xml-файлы для отправки в различные органы и желающих проверить их правильность, XML Viewer, думаю, будет незаменим, поскольку упор при показе делается на текстовое содержимое внутри тегов, поскольку именно в нем, чаще всего, сосредоточена полезная информация.
Ну а для скриптописателей XML Viewer может служить учебным пособием.

Более подробное описание (с картинкой) - тут.
Код размещен - тут.
История изменений - тут.
Упакованный в zip можно скачать - тут

2

Re: HTA: XML Viewer

Выложите архив, если не трудно.

Автоматизирую торговлю. Не 1С

3 (изменено: mozers, 2012-01-16 00:09:57)

Re: HTA: XML Viewer

не трудно

4

Re: HTA: XML Viewer

1. Приложение выдал ошибку Access is denied на на строке 187. Версия XMLViewer v.1.0.0.
2. Раздражает постоянно выскакивающее окно запроса Associate XML-files with the XMLViewer?, которое по клавише ESC не исчезает.
3. Что нового дает Ваше приложение по сравнению с браузерами, которые умеют отображать любые xml-файлы - как well-formed так и не well-formed?

( 2 * b ) || ! ( 2 * b )

5

Re: HTA: XML Viewer

2Rumata
1. Закомментируйте эту строку Или так: IE - Параметры безопасности - "Разрешать запущенные скриптом окна без ограничений на размеры и положение".
2. Да, пожалуй я чересчур назойлив - поправлю.
3. Лишь упрощеннный и наглядный способ отображения. Все видно на скрине.

6 (изменено: Rumata, 2012-01-16 14:57:50)

Re: HTA: XML Viewer

Понял. Еще несколько позитивных замечаний-предложений.

1.
Ваше приложение

    window.resizeBy(idXML.offsetWidth-document.body.offsetWidth+40, 0);

У меня есть приложение, в котором устанавливаются размеры окна

    window.resizeTo(w, h);

Ваше приложение генерирует исключение, мое работает и выполняет эту строку. Вы не в курсе в чем может быть проблема?

2.
Предлагаю распространять совместно соответствующий .reg-файл или даже .bat-файл, который зарегистрирует Ваше приложение для просмотра xml-файлов.

3.
Попробуйте "скормить" приложению невалидный xml-файл или html(hta)-файл - увидите, что работает очень медленно.

4.
Коллекция элементов просто и понятно перебирается обычным циклом.
Вместо

        var nodeChilds = new Enumerator(Node.childNodes);
        for (; !nodeChilds.atEnd(); nodeChilds.moveNext()){

напишите

        for (var i = 0; i < Node.childNodes.length; i++){

Заодно избавитесь от ненужной проверки if (Node.childNodes.length > 0) {. Видимо с обработкой атрибутов выше - аналогично.

5.
Не вдавался в подробности генерируемого кода - как выглядит изнутри html-код представления разворачивающегося/сворачивающегося xml-дерева? Таблицы? Можно сделать проще с помощью нескольких div-ов. Таблицы не самый лучший структуро-определяющий тег.

6.
Эту функцию

function Space(count){

можно переписать так

function Space(count)
{
    return new Array(Number(count) + 1).join('&nbsp;');
}

или даже так

String.prototype.repeat = function(count)
{
    return new Array(Number(count) + 1).join('&nbsp;');
}

var spaces10 = '&nbsp;'.repeat(10);

7.
Если эта функция

function GetElementIndex(Arr, elem){

используется ТОЛЬКО для массивов (не для коллекций элементов), то можно написать, например, так:

Array.prototype.indexOf = function(elt)
{
    var len = this.length;
    for (var i = 0; i < len; i++) {
        if ( this[i] === elt ) {
            return i;
        }
    }
    return -1;
};

[0, 1, 2, 3].indexOf(0) == 0
[0, 1, 2, 3].indexOf(2) == 2
[0, 1, 2, 3].indexOf(4) == -1

8. Не пишите так, это очень медленно и сильно ощущается замедление на больших циклах:

var s = '';
for (var i = 0; i < n; i++) {
    s += ...;
}

Лучше пишите так

var s = [];
for (var i = 0; i < n; i++) {
    s.push(...);
}
... s.join('');
( 2 * b ) || ! ( 2 * b )

7

Re: HTA: XML Viewer

2Rumata
1. window.resizeTo реально меняет размеры окна и не вызывает ошибку на той же машине где window.resizeBy не срабатывает??? Оччень странно это... Я - в шоке
2. Заменить весь функционал установки ассоциации батником будет весьма и весьма сложно. Исключил предложение о регистрации из загрузки и повесил на F10.
3. Вероятно "невалидный xml" оказался в utf-8. Да, тут открытие происходит дважды (сначала - в 1251, детектирование, затем utf-8). Так что возможно на больших файлах может и подтормаживать. Пока идей как ускорить этот процесс - нет. Остается одно - реже делать ошибки в xml
4. Да, затупил маленько. Исправил, вставив несколько необычный, но (по мнению спецов) весьма быстрый цикл. Да и код существенно ужался. Спасибо!
5. Таблицы я очень люблю. Имхо просто и понятно. Скрывать - всегда одинаково style.display='none'. А кому это присваивать DIV-у или ряду таблицы - какая разница?
Вот только у меня ф-ция скрытия строк наперед не знает что будет скрывать и анализирует строки таблицы. Я так понял что Вы предлагаете расставить DIV-ы заранее, в момент построения списка. Тут - соглашусь - скрытие работать будет быстрее (забудем что тормоза при скрытии можно обнаружить только со специальным оборудованием). Но как правильно расставить DIV-ы? Тут алгоритм получается хитрый - тут думать надо...
6. Space - заменил на Вашу. Моя мне сразу не понравилась
7. GetElementIndex пользую часто. Для коллекций даже чаще чем для массивов. Но все равно, после Вашего пинка, переписал аккуратней.
8. Учту на будущее. А, кстати,  s[s.length]=... будет побыстрее s.push(...) хотя че мы тут сотые доли милисекунды ловим? имхо наглядность кода - более важный критерий.

В общем, СПАСИБО, за толковые замечания. Код поправил.
Все изменения - тут.
ZIP - тут.

8 (изменено: Rumata, 2012-01-17 00:45:51)

Re: HTA: XML Viewer

mozers пишет:

невалидный xml

Это readme.html из архива.

mozers пишет:

1. window.resizeTo реально меняет размеры окна и не вызывает ошибку на той же машине где window.resizeBy не срабатывает???

Да.

window.resizeBy
Видимо проблема в том, что на моей машине происходит изменение в отрицательную сторону. Я сделал следующую замену

    alert([idXML.offsetWidth-document.body.offsetWidth+40, 0]);
//    window.resizeBy(idXML.offsetWidth-document.body.offsetWidth+40, 0);

И получил следующий результат.

---------------------------
XMLViewer v.1.0.0
---------------------------
-692,0
---------------------------
OK   
---------------------------

Проверьте по спецификации метода - что конкретно он делает и какие значения аргументов допустимы.
И что означает выражение idXML.offsetWidth-document.body.offsetWidth+40?

( 2 * b ) || ! ( 2 * b )

9 (изменено: Rumata, 2012-01-18 00:55:26)

Re: HTA: XML Viewer

mozers пишет:

5. Таблицы я очень люблю. Имхо просто и понятно. Скрывать - всегда одинаково style.display='none'. А кому это присваивать DIV-у или ряду таблицы - какая разница?
Вот только у меня ф-ция скрытия строк наперед не знает что будет скрывать и анализирует строки таблицы. Я так понял что Вы предлагаете расставить DIV-ы заранее, в момент построения списка. Тут - соглашусь - скрытие работать будет быстрее (забудем что тормоза при скрытии можно обнаружить только со специальным оборудованием). Но как правильно расставить DIV-ы? Тут алгоритм получается хитрый - тут думать надо...

Таблицы тяжело поддерживать - по-хорошему надо соблюдать вложенность тегов table-tr-td. В первой же версии что-то нарушилось:

		// парсинг XML документа
		html = '<table id="idXML" cellspacing="0"><td>';

Действия скрыть/показать можно делать как через style.display='none', так и через добавление/удаление класса. Например:

// стилевой правило
.hidden	{
	display: none;
}
// фукнция переключения состояния скрыть/показать
// требует описания дополнительных функций
// hasClass - проверяет наличие класса у тега
// addClass - добавляет класс к тегу
// delClass - удаляет класс у тега
function toggle(el, className)
{
	if ( hasClass(el, className) ) {
		delClass(el, className);
	} else {
		addClass(el, className);
	}
};

// обработка события клик мышкой
document.onclick = function(e)
{
	e = e || window.event;
	var el1 = e.srcElement;
	if ( ...) {
		// клик на теге el1 изменяет отображение тега el2
		var el2 = ...
		toggleClass(el2, 'hidden');
	}
};

На первый взгляд это может показаться громоздким, но только на первый взгляд. На самом деле это очень удобный и универсальный способ. Решения, основанные на таком способе можно найти в сети, если возникнет желание узнать мое мнение или почитать мои объяснения, могу подготовить развернутый текст для коллекции.

А вот пример html-кода:


<div class="outer">
<h1>кликая строку 1</h1>
<div class="inner">разворачиваем или сворачиваем блок 1
	<div class="outer">
	<h1>кликая строку 1.1</h1>
	<div class="inner">разворачиваем или сворачиваем блок 1.1</div>
	</div>

	<div class="outer">
	<h1>кликая строку 1.2</h1>
	<div class="inner">разворачиваем или сворачиваем блок 1.2</div>
	</div>
</div>
</div>

<div class="outer">
<h1>кликая строку 2</h1>
<div class="inner">разворачиваем или сворачиваем блок 2</div>
</div>

Однако основная проблема производительности - это генерация html-кода на основе входящего xml-файла. Это весьма трудоемкий процесс (рекурсивный вызов функции, неоптимальный алгоритм конкатенации строк самим jscript. Может имеет смысл переложить работу на другие плечи?


// xsl-файл преобразования xml в html
var xslFile = ...
oXslDom.load(xslFile);

// другой вариант хранить и грузить xsl как строку
oXslDom.loadXml(xslString);

// входной xml-файл
var xmlFile = ...
oXmlDom.load(xmlFile);

// инициализировать процессор
var oProcessor = new XSLTProcessor();
oProcessor.importStylesheet(oXslDom);

// выполнить преобразование
var oResultDom = oProcessor.transformToDocument(oXmlDom);
alert(oResultDom.xml);
( 2 * b ) || ! ( 2 * b )

10

Re: HTA: XML Viewer

2Rumata
Извините великодушно (занимался перетаскиванием всех моих разрозненных проектов в одно место), на форум не заходил и Ваши ответы не читал
Сейчас буду изучать...
А проблему с "Access is denied" при window.resizeTo (или window.resizeBy) обнаружил на виртуалке с XP SP3.
Стабильно ловится всегда с любой hta-шкой в которой есть window.resizeTo/resizeBy. Достаточно лишь после даблклика на иконке приложения хотя бы пол-секунды не отпускать кнопку мыши.
Поискал решение в инете - не нашел ничего путного. Мелкософт предлагает править реестр - мне не помогло.
Покумекал - сочинил сам. Работает

11

Re: HTA: XML Viewer

2Rumata

<table id="idXML" cellspacing="0"><td>

Да, <td> тут - закралась по ошибке.

Действия скрыть/показать можно делать как через style.display='none', так и через добавление/удаление класса

Нормальный метод. И пример - наглядный. Взял на заметку. ИМХО применение его оправдано когда надо изменять не один стилевой параметр (как у меня) а несколько (допустим, одновременно изменить бекграунд, цвет и начертание текста).
А пример html ниже можно заставить работать как и через добавление/удаление класса, так и через style.display='none'.
Тут главное - правильно расставить DIV-ы (правда потеряем дополнительное время на парсинге файла).

var oProcessor = new XSLTProcessor();

Эта фишка в IE (а значит и в HTA) не работает. В IE доступен только метод transformNode. Но, увы, я не в курсе как фиксированная таблица стилей сможет помочь нам с парсингом произвольного XML документа.

12

Re: HTA: XML Viewer

mozers пишет:

Эта фишка в IE (а значит и в HTA) не работает. В IE доступен только метод transformNode

А-а-а. Ну так это же прекрасно. Я виноват - в том примере я не обратил внимание и привел код адаптации Мозиллы под некоторые удобные средства МСИЕ.

mozers пишет:

как фиксированная таблица стилей сможет помочь нам с парсингом произвольного XML документа.

Я сам не являюсь знатоком xslt-преобразований. Всего ли один пример из двух файлов из когда-то читаной книжки по xslt, кажется, Стивена Хользнера. Сохраните два файла в один каталог и посмотрите результат в любом из браузеров. Или запустите пример на JScript/

planets.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="./planets.xsl"?>
<PLANETS>

  <PLANET>
    <NAME>Merciry</NAME>
    <MASS UNITS="(Earth = 1)">.0553</MASS>
    <DAY UNITS="days">58.65</DAY>
    <RADIUS UNITS="miles">1516</RADIUS>
    <DENSITY UNITS="(Earth = 1)">.983</DENSITY>
    <DISTANCE UNITS="million miles">43.4</DISTANCE>
  </PLANET>

  <PLANET>
    <NAME>Venus</NAME>
    <MASS UNITS="(Earth = 1)">.815</MASS>
    <DAY UNITS="days">116.75</DAY>
    <RADIUS UNITS="miles">3716</RADIUS>
    <DENSITY UNITS="(Earth = 1)">.943</DENSITY>
    <DISTANCE UNITS="million miles">66.8</DISTANCE>
  </PLANET>

  <PLANET>
    <NAME>Earth</NAME>
    <MASS UNITS="(Earth = 1)">1</MASS>
    <DAY UNITS="days">1</DAY>
    <RADIUS UNITS="miles">2107</RADIUS>
    <DENSITY UNITS="(Earth = 1)">1</DENSITY>
    <DISTANCE UNITS="million miles">128.4</DISTANCE>
  </PLANET>

</PLANETS>

planets.xsl

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="/">
    <HTML>
    <HEAD>
    <TITLE>The Planets Table</TITLE>
    </HEAD>

    <BODY>
    <H1>The Planets Table</H1>

    <TABLE BORDER="1">
    <TR>
      <TD>Name</TD>
      <TD>Mass</TD>
      <TD>Radius</TD>
      <TD>Day</TD></TR>
      <xsl:apply-templates/>
    </TABLE>
    </BODY>
    </HTML>
  </xsl:template>

  <xsl:template match="PLANETS">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="PLANET">
    <TR>
      <TD><xsl:value-of select="NAME"/></TD>
      <TD><xsl:apply-templates select="MASS"/></TD>
      <TD><xsl:apply-templates select="RADIUS"/></TD>
      <TD><xsl:apply-templates select="DAY"/></TD></TR>
  </xsl:template>

  <xsl:template match="MASS">
    <xsl:value-of select="."/>
    <xsl:value-of select="@UNITS"/>
  </xsl:template>

  <xsl:template match="RADIUS">
    <xsl:value-of select="."/>
    <xsl:value-of select="@UNITS"/>
  </xsl:template>

  <xsl:template match="DAY">
    <xsl:value-of select="."/>
    <xsl:value-of select="@UNITS"/>
  </xsl:template>

</xsl:stylesheet>

planets.js


var xmlFile = 'planets.xml';
var xslFile = 'planets.xsl';

var xmlDom = new ActiveXObject('Microsoft.XMLDOM');
xmlDom.load(xmlFile);

var xslDom = new ActiveXObject('Microsoft.XMLDOM');
xslDom.load(xslFile);

var result = xmlDom.transformNode(xslDom);

WScript.Echo(result);
mozers пишет:

Нормальный метод. И пример - наглядный. Взял на заметку. ИМХО применение его оправдано когда надо изменять не один стилевой параметр (как у меня) а несколько

Его удобно применять везде )))

( 2 * b ) || ! ( 2 * b )

13

Re: HTA: XML Viewer

2Rumata
В приведенном примере используется индивидуальная таблица стилей planets.xsl предназначенная для обработки конкретного файла planets.xml.
Т.е. для обработки другого файла надо использовать совершенно другую таблицу стилей.
Возможно что её можно как то создать динамически, проведя анализ открываемого xml файла. Но на такой анализ и динамическое создание xls уйдет наверняка больше времени чем на одноразовый парсинг.

14

Re: HTA: XML Viewer

mozers пишет:

В приведенном примере используется индивидуальная таблица стилей

Мда. Вы правы. Вообще, я предполагаю, что можно составить такой xsl-файл, чтобы можно было выполнить XML-2-XML преобразования. Но насколько это будет универсальный файл сказать не могу.

( 2 * b ) || ! ( 2 * b )

15

Re: HTA: XML Viewer

Такой xsl-файл зашит в IE и работает при открытии валидного XML (без ссылки на xslt) в браузере.

16

Re: HTA: XML Viewer

XML Viewer 2.0.0
Приложение полностью переписано.
Теперь результат парсинга XML представлен в виде списка, строки которого формируются "на лету" по всем законам DHTML.
Так же, в виде списка, теперь показывается результат парсинга файлов имеющих ошибку в xml структуре.
Это позволило максимально упростить и повысить наглядность кода. При этом наглядность отображения результата ничуть не пострадала.
Многие функции - универсальны и с успехом могут использоваться в ваших приложениях.
Ссылки - прежние: описание, код, zip.

2Rumata
Надеюсь что теперь придраться будет не к чему

2Serge Yolkin
Только как это дело можно использовать в наших целях - совершенно непонятно.

17

Re: HTA: XML Viewer

Сделал уже несколько обновлений. И каждый раз думал, что это - последний вариант и более оптимальный вариант кода просто невозможен.
И каждый раз убеждался в своей наивности. Воистину - совершенству нет предела
Попались хитрые xml-файлики в которых текст узла разбит вложенными тегами. Как выяснилось, даже любимый мной STDU XML Editor такие финты отображает не совсем корректно, сваливая вложения в одну кучу.
В общем, научил XML Viewer справляться с этим делом, а так же распознавать xml-комментарии.
Кстати, по поводу скорости работы: 1,5 Мб xml-файл в XML Viewer у меня открывается заметно быстрее чем в голом IE.
Так что к идее обработки XML с помощью таблицы стилей я все больше и больше охладеваю. Разве что чисто в исследовательских целях...
XML Viewer 2.3.0

18

Re: HTA: XML Viewer

В последних версиях вьюер вполне приличный. Пожелание: сделать (можно опционально) исключение для пространства имен hta: - тогда можно будет проверять хэтэашки на соответствие XHTML. .html файлы можно проверять уже сейчас.

На счет - как поможет - не знаю. Я отвечал на предположение уважаемого Rumata постом выше.

На счет голого ИЕ: БРАУЗЕР ИЕ уже не голый. Локальные .html и валидные .xml файлы я открываю таким вот .hta файликом (принимает имя файла в качестве параметра комстроки):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta http-equiv="MSThemeCompatible" content="yes" />
  <meta http-equiv="X-UA-Compatible" content="IE=9" />
  <meta http-equiv="Content-Language" content="ru" />
  <meta http-equiv="imagetoolbar" content="no" />
  <hta:application
   applicationName="WB-IXb"
   icon="%SystemRoot%/system32/mshtml.dll"
   id="HTApp"
   innerBorder="no"
   navigable="yes"
   version="0.5"
   />
  <style type="text/css" >
    body,#wb{border:none;height:100%;margin:0;padding:0;width:100%;}
    body{overflow:hidden;}
    #wb{position:absolute;}
  </style>
</head>
<body onload="moveTo(60,30);document.getElementById('wb').src=HTApp.commandLine.replace(/^\u0022.*\u0022\s+/,'').replace(/\u0022/g,'');">
  <iframe frameborder="0" id="wb" onload="document.title=' Просмотр: '+this.src.replace(/^file:\/\/\//,'');"></iframe>
</body>
</html>

Тот же ИЕ, но без браузерных наворотов запускается заметно быстрее, особенно на дохленьком нотнике.

19

Re: HTA: XML Viewer

Serge Yolkin пишет:

сделать (можно опционально) исключение для пространства имен hta:

Дело в том, что весь парсинг осуществляет ActiveX "Msxml2.DOMDocument". Скрипт лишь показывает результаты его работы.
Заставить XMLParser игнорировать при анализе то или иное пространство имен, имхо, нельзя. Ну во всяком случае я у него такого свойства не обнаружил.

20 (изменено: Rumata, 2012-02-01 17:02:39)

Re: HTA: XML Viewer

Большая критика в адрес Вашей программы. Программа сама не проходит валидацию, и не является правильно сформированным xml-файлом. Имею ввиду не тег hta:application, а именно весь документ.

Еще одно замечание. Если документ невалидный, то он отображается как простой текст, в соответствующем месте выводится сообщение об обнаруженной ошибке. В таком случае нет смысла выводить весь текст файла, если ошибка находится "за кадром", то ее не видно, пока не прокрутишь весь файл в окне. лучше выводите проблемную строку, ее номер в файле (если такое возможно), и текст ошибки.

( 2 * b ) || ! ( 2 * b )

21

Re: HTA: XML Viewer

Rumata пишет:

Большая критика в адрес Вашей программы. Программа сама не проходит валидацию, и не является правильно сформированным xml-файлом. Имею ввиду не тег hta:application, а именно весь документ.

А с какого перепугу HTA (или HTML) код должен быть "правильно сформированным xml-файлом" ???

Rumata пишет:

если ошибка находится "за кадром", то ее не видно, пока не прокрутишь весь файл в окне.

Ага, добавлю прокрутку. Возможно и стоит обрезать лишний код, если файл - огромный... Но выводить только проблемную строку, имхо, маловато... Подумаю...

22

Re: HTA: XML Viewer

Весьма неплохо.
Потянет и как вьювер других файлов.

Но виснет при загрузке относительно больших файлов (100 kb).
// как выяснилось, из-за большого количества строк (перенумерация которых съедает ресурсы). 2-3 тысячи CRLF вызывают изрядное зависание.

Заметил баг:
- При запуске через Drag'n'Drop не обрабатывает имена содержащие пробелы.

23

Re: HTA: XML Viewer

xml-файл размером 1.3 МБ открывается примерно одинаково, около от 3 до 6 секунд - в МСИЕ дольше чем в HTA. В последнем с помощью xsl-стилей отрисовка происходит действительно ощутимо быстрее

( 2 * b ) || ! ( 2 * b )

24

Re: HTA: XML Viewer

Возможно от структуры зависит, но не думаю.
Сколько строк в том файле?

Я взял XML без стилей размером в 200kb/3500 строк (БД от записной книжки - http://www.forum.script-coding.com/view … ?pid=15557).
Обработал за 50 секунд...

25

Re: HTA: XML Viewer

1.3 МБ это порядка 20-40 тысяч строк. Кстати разница не такая уж и большая при смене браузера - например, ФФ или Хром. И известна причина - отрисовка большущей портянки документа.

С использованием CSS и XSL задача решается весьма элегантно - стили задают отображение элементов, XSL - отвечает за преобразование входного документа, а порция JS-кода отвечает за динамику (свернуть/развернуть узел, открыть файл).

( 2 * b ) || ! ( 2 * b )

26

Re: HTA: XML Viewer

mozers пишет:

А с какого перепугу HTA (или HTML) код должен быть "правильно сформированным xml-файлом"

В данном случае - из идеологических соображений. HTML И XML имеют "братские" отношения. Программа, генерирующая результат из одного формата в другой родственный и частично написанная на одном из них, должна пройти проверку. Это всего лишь мое мнение.

mozers пишет:

Но выводить только проблемную строку, имхо, маловато..

Не важно, что было до проблемной строки, и тем более не важно, что будет после нее. Если есть ошибка - ее надо искать в исходном файле, а не в данном отображении. Поэтому достаточно вывода проблемной строки.

mozers пишет:

Т.е. для обработки другого файла надо использовать совершенно другую таблицу стилей.
Возможно что её можно как то создать динамически, проведя анализ открываемого xml файла. Но на такой анализ и динамическое создание xls уйдет наверняка больше времени чем на одноразовый парсинг.

Можно написать один единственный файл, который можно применить ко всем xml-файлам.

Мне и самому уже стало интересно поразбираться в этой задаче. Не желаете ли взглянуть на мои скромные потуги? )))

( 2 * b ) || ! ( 2 * b )

27

Re: HTA: XML Viewer

2Аскет
Не уверен насчет того что в тормоза зависят от количества строк. Может и так, но код обработки никак их не отличает от всех остальных остальных символов. Так что тут поправлять просто нечего.

Нашел шикарные файлы для тестирования. Это - формы для стат.отчетности. Размер варьируется от 10кБ до 2МБ. Тормоза при обработке ощущаются конкретные. Анализ показал, что главную задержку дает не парсер (строка xmlDoc.load), а обработка результатов его анализа (процедура ParseNode). Причем до 99% времени. Так что поле для модернизации - просто огромное. Правда как модернизировать - пока не ясно...

Rumata пишет:

В данном случае - из идеологических соображений. HTML И XML имеют "братские" отношения. Программа, генерирующая результат из одного формата в другой родственный и частично написанная на одном из них, должна пройти проверку. Это всего лишь мое мнение.

Позвольте не согласиться. Ни по одному заявлению.

Rumata пишет:

Если есть ошибка - ее надо искать в исходном файле, а не в данном отображении.

Если только не предположить что код можно будет изменить. Прямо в этом же окне XMLViewer

Rumata пишет:

Можно написать один единственный файл, который можно применить ко всем xml-файлам.

Универсальный файл позволяет изменить лишь "рюшечки" (цвет, шрифты и пр.). Вся фишка XMLViewer - в способе представления данных, что с помощью одного универсального xls файла, реализовать, боюсь, будет невозможно

28

Re: HTA: XML Viewer

mozers пишет:

Позвольте не согласиться. Ни по одному заявлению.

С этим-то не согласиться Вы не сможете )))

Rumata пишет:

Это всего лишь мое мнение.

mozers пишет:

можно будет изменить

Даже если так. Для редактирования - показать исходный код и отмотать к заданной строке.

mozers пишет:

Универсальный файл позволяет изменить лишь "рюшечки" (цвет, шрифты и пр.). Вся фишка XMLViewer - в способе представления данных, что с помощью одного универсального xls файла, реализовать, боюсь, будет невозможно

Рюшечки менять надо с помощью CSS, хотя можно и с помощью XSL, и на это есть средства в XSL. Прошу Вас, не примите за обиду, но в программе XMLViewer нет фишек, она лишь отображает произвольный xml-файл. Это умеют делать все современные графические браузеры. А универсальный xsl-файл реализовать можно.

( 2 * b ) || ! ( 2 * b )

29

Re: HTA: XML Viewer

Хотел бы присоединиться к дискуссии.
1) Вообще, innerHTML работает на порядок быстрее createElement с appendChild.
2) documentElement.xml выдает форматированный текст XML. Может быть стоит применить к нему RegExp для изменения содержания?

30

Re: HTA: XML Viewer

JSman пишет:

nnerHTML работает на порядок быстрее createElement с appendChild

Есть экспериментальные подтверждения?

( 2 * b ) || ! ( 2 * b )

31

Re: HTA: XML Viewer

Rumata пишет:

Для редактирования - показать исходный код и отмотать к заданной строке.

Так и сделал (коммит будет чуть позднее). Только прошу учесть что ошибка может быть совсем не в той строке на которую ругается парсер. (Типичный пример - это когда тег конца не соответствует тегу начала). Так что в любом случае выводить только строку с ошибкой - явный прокол.

Rumata пишет:

Прошу Вас, не примите за обиду, но в программе XMLViewer нет фишек, она лишь отображает произвольный xml-файл. Это умеют делать все современные графические браузеры.

Обид - нет Просто, объясните себе пожалуйста нафига нужен XMLViewer когда кругом полно самых разнообразных браузеров, которые отображают xml код быстрее и лучше

JSman пишет:

innerHTML работает на порядок быстрее createElement с appendChild

Ну вот. Хотел как лучше...
На слово не поверю (извините) - ща переделаю процедуру и посмотрю. Хотя чисто по человечески обидно возвращаться взад. Если выгрыш в скорости будет несущественный (я наставил в коде счетчики - смогу сказать точно) то оставлю все как есть.

JSman пишет:

documentElement.xml выдает форматированный текст XML. Может быть стоит применить к нему RegExp для изменения содержания?

Чисто умозрительно этот способ кажется самым длительным из всех.

С редактированием, увы - только идея. Точнее, редактировать можно запросто (contentEditable). Но, как выяснилось, во всех строках табуляция самопроизвольно заменяется на пробелы. Т.е. исправленный сохраненный файл будет отличаться от исходного не только исправленной строкой. Не думаю что это кому то понравится. Как решить - пока не придумал.

32

Re: HTA: XML Viewer

Вот линк для проверки. Только в IE откройте:)

33

Re: HTA: XML Viewer

Ну вот и готово.

    function ParseNode2(Node)
    {
        var Result=[], ElementCount=0;
        var Text = Node.xml.replace(/\r?\n/g, " ").replace(/>\s+</g, "><").replace(/\/>/g, "></tag>").replace(/"\s+>/g,"\">");

        function ParseElement(m)
        {
            var Name="", Attrs=[], AttrsCode=[];;
                m=m.replace(/^([^ ]+) */, function (q, q1) {Name=q1; return ""});
                
                Name="<UL><LI><SPAN class=name>"+Name+"</SPAN>";
                if (m=="") return (Name);
                
                Attrs = m.split(/="|"/);
                for (var i=0, l=Attrs.length; i<l; i+=2)
                {
                    AttrsCode.push("<SPAN class=aname>"+Attrs[i]+"</SPAN><SPAN class=text>:</SPAN><SPAN class=avalue>"+Attrs[i+1]+"</SPAN>")
                }
                
            return (Name+AttrsCode.join(""));
        }
        
        function operate(m)
        {
            var add="";
            
            if (/<!--/.test(m)) return "<SPAN class=comment>"+m.replace(/^<!--/, "").replace(/-->$/, "")+"</SPAN>";
            if (/<\//.test(m)) return ("</LI></UL>"+add);
            if (/</.test(m)) return (ParseElement(m.replace(/[<>]/g, ""))+add);
            return "<SPAN class=value>"+m+"</SPAN>"+add;
        }
        
        Text=Text.replace(/<!--.*-->|<[^<>]+>|[^<>]+/g, operate)
        idRange.innerHTML = Text;
    }

Тестирую так:

        } else {
            // парсинг XML документа
            var D=new Date();
            var oUL = CreateElement(idRange, 'UL');
            //ParseNode (xmlDoc.documentElement, oUL);
            ParseNode2 (xmlDoc.documentElement, oUL);
            alert(new Date() - D);
            
            // добавляем эвент для свертки строк
            document.onclick = function() {
                var parentLI = GetParent(event.srcElement, 'LI');
                if (parentLI) ShowHide(parentLI);
            };
        }

Алерт выведет время парсинга.

Полный файл тут.

Строки замены 196, 197.

Потом покажу как XML файл размером в 10МБ отобразить за минуту на медленном компе)  Выше немного другой алгоритм, более медленный.

34

Re: HTA: XML Viewer

2JSman
Не поверил авторитетной ссылке. Проверил все сам.
Оказалось что отображение результатов с помощью innerHTML работает более чем в 40 раз быстрее, чем с помощью createElement и appendChild.
Печально Такой наглядный и аккуратный код был...
С innerHTML так красиво не получится...
Возьму за образец Ваш код. Не возражаете?

35

Re: HTA: XML Viewer

А будет ли настолько же надёжно работать, как с добавлением листьев?

36

Re: HTA: XML Viewer

mozers пишет:

Не поверил авторитетной ссылке. Проверил все сам.
Оказалось что отображение результатов с помощью innerHTML работает более чем в 40 раз быстрее, чем с помощью createElement и appendChild.
Печально  Такой наглядный и аккуратный код был...
С innerHTML так красиво не получится...
Возьму за образец Ваш код. Не возражаете?

Я думаю, что не стоит переживать из-за наглядности кода. Ведь, главное, что он работает и справляется с задачей . По поводу использования абсолютно не возражаю. Однако при распространении кода с указанием Вашего псевдонима как автора, прошу также указать и мой ник. Думаю, что это вполне справедливо.

alexii пишет:

А будет ли настолько же надёжно работать, как с добавлением листьев?

Не могли бы уточнить вопрос?

37

Re: HTA: XML Viewer

Сравнил результаты обработки БД (размером в 187 kb) от вышеупомянутой записной книжки.

Заметно быстрее - ~30 сек. против ~50 сек. на прошлом тесте.
Посему, самое узкое место программы - не там.

38

Re: HTA: XML Viewer

«.innerHTML» позволяет задать произвольную строку, так?! Есть ли уверенность в том, что она будет корректна?

39

Re: HTA: XML Viewer

Обсуждение пошло в странном направлении. Почему то никто не желает смотреть в сторону XSLT. Почему? Вы знаете, что там есть проблемы? Или просто недостаточно знаний в этой области?

( 2 * b ) || ! ( 2 * b )

40 (изменено: Аскет, 2012-02-04 17:47:05)

Re: HTA: XML Viewer

«.innerHTML» позволяет задать произвольную строку, так?! Есть ли уверенность в том, что она будет корректна?

Ну если «абсолютной валидности», то можно в принципе интегрировать обоих.
Как по скорости будет не скажу, но судя по всему примерно 50% от предложенного JSman'ом

var A = document.CreateElement ("AnyTag")
document.all.anyExistsContainer.innerHTML = A.OuterHTML

41

Re: HTA: XML Viewer

Rumata пишет:

Обсуждение пошло в странном направлении. Почему то никто не желает смотреть в сторону XSLT. Почему? Вы знаете, что там есть проблемы? Или просто недостаточно знаний в этой области?

Ну, почему же в странном? Сейчас добавлю поддержку комментариев и разберусь с проблемой Аскета и можно будет шаблонами заняться.

Вы бы лучше свою наработку показали. Обсуждать лучше конкретный код.

42

Re: HTA: XML Viewer

alexii пишет:

«.innerHTML» позволяет задать произвольную строку, так?! Есть ли уверенность в том, что она будет корректна?

Да, в конечном счете она будет корректна. Так как HTML 4 довольно устойчивый к ошибкам язык.

43

Re: HTA: XML Viewer

Аскет пишет:

Как по скорости будет не скажу, но судя по всему примерно 50%

Или, быть может,  форматирование тэга более трудозатратная операция нежели его вставка.
Нет, всё же вставка элемента более ресурсоемкая операция (поиск места и узла, вставка), ИМХО.

44

Re: HTA: XML Viewer

JSman пишет:

Да, в конечном счете она будет корректна. Так как HTML 4 довольно устойчивый к ошибкам язык.

Ах да! Дадада )

Я ведь буквально давеча написал винтажный валидатор для HTML.
И именно (и только) на основе прогона "грязного HTML" через ядро HTML.

45

Re: HTA: XML Viewer

Прога претерпела ряд существенных изменений.
Самое существенное - новый алгоритм парсинга (автор: JSman).
Скорость работы дико возросла.

Последний вариант.

46 (изменено: Аскет, 2012-02-04 21:10:33)

Re: HTA: XML Viewer

Вот это уже другое дело!
«Злостную» XML-ку обработал за ~5 сек (при 46 mb свободной памяти).
А какие в нем отличия от предложенного JSman'ом в 33#? Время сильно разнится.

Но после загрузки файла выдаёт ошибку:

На этой странице произошла ошибка сценария. 

Строка:      260
Символ:      5
Ошибка:      "1" -  есть null или не является объектом
Код:      0
URL:      file://C:\hidenPATH\XMLViewer.hta 

Продолжить выполнение сценариев на этой странице?

47

Re: HTA: XML Viewer

Аскет пишет:

А какие в нем отличия от предложенного JSman'ом  в 33#? Время сильно разнится.

Да ничем чтобы могло сказаться на скорости. Чисто оформление да еще JSman добавил распознавание комментариев.

Насчет ошибки - я в ступоре. В строке 260 ничего чтобы могло вызвать такую ошибку - нет
Кстати, JSman исправил еще баг с Drag'n'Drop с именами содержащими пробелы.
Новая версия.

48

Re: HTA: XML Viewer

Аскет, у меня такой ошибки не обнаружилось (виста, мсие 7)

Вопрос к авторам. mozers, JSman, по какой логике объявляете функции в приложении? Конечному пользователю все равно, но если разработчик пожелает посмотреть принцип работы определенных функций, то будет удивлен из расположением. ))) Меня удивило, что ParseError, ParseXML, LoadXMLFile, ReadFile раскиданы по всему файлу. Обычное размещение скриптов - в заголовке, в теле документа - при особой необходимости. В данном случае особой необходимости в этом нет.

( 2 * b ) || ! ( 2 * b )

49

Re: HTA: XML Viewer

2Rumata
Какие то странные правила для размещения функций. Сами придумали?
В теле вообще то скриптов - нет. Не вижу криминала если бы и были...
Функции ReadFile, ParseError, SetFileAssociation, RegDeleteKeys помещены отдельно, чиста для наглядности, поскольку они не относятся к основному функционалу программы и почти не зависят от функций верхней половины.

50

Re: HTA: XML Viewer

Rumata, Вы бы что-нибудь дельное посоветовали бы. Вот, например, как на Ваш взгляд отобразить объемный XML?

51

Re: HTA: XML Viewer

Решил и я добавить пару слов в тему.

Обсудив с коллегой JSman-ом столь удобный инструмент просмотра XML файлов, я пришёл к выводу, что хотелось бы иметь фильтр по маске в нём. Дабы показывать только XML файлы. Предлагаю такой вариант:

Объект input, который предоставляет диалог выбора файла заменить на:


	<object id=HtmlDlgHelper classid="clsid:3050F4E1-98B5-11CF-BB82-00AA00BDCE0B"></object>

и вот как то так поправить функцию выбора файла


	function DialogOpenFile() {
		var fname = HtmlDlgHelper.openfiledlg("","","XML файлы (*.xml)|*.xml;|Все файлы (*.*)|*.*|","Выберите файл...")
		if (!fname) self.close(); // при отказе от выбора закрываем приложение
		idRange.innerHTML = '';
		current_file = fname;
	}

Если лень править код, вот ссылка на готовый пример.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

52

Re: HTA: XML Viewer

Xameleon , а вот и ссылка для закачки

53

Re: HTA: XML Viewer

mozers пишет:

Какие то странные правила для размещения функций. Сами придумали?
В теле вообще то скриптов - нет. Не вижу криминала если бы и были...

Объявить объект до его использования - нормальная практика программирования, придуманная не мной. Криминала нет. И логики тоже нет. )))

JSman пишет:

дельное посоветовали бы

Чуть ли не с самого начала предлагаю смотреть в сторону XSLT, который отобразит XML любых размеров согласно заданной разметке.

( 2 * b ) || ! ( 2 * b )

54

Re: HTA: XML Viewer

Rumata пишет:

Объявить объект до его использования - нормальная практика программирования

Всему должно быть объяснение. Есть объяснение и для таких требований.
Данные рекомендации относятся к веб-страницам, загружаемым по сети. Если функция или объект будет вызвана до его загрузки, то может произойти ошибка. Чтобы этого не происходило, на веб-страницах код функций и объектов располагают выше (до кода который их использует).
Преждевременного вызова функций можно избежать и другим способом - не вызывать их до полной загрузки страницы. Т.е. производить запуск всех процедур после события body onload.
Что касается WSH VBS и JS скриптов тут можно совсем не парится, поскольку их выполнение начинается только после полной загрузки всего скрипта в память.
HTA - ближе к веб-страницам чем к WSH. Т.е. загрузка скриптов (особенно внешних) может занимать некоторое время (конечно, меньше чем у веб-страницы, но всетаки...). Но запуск всех действий по body onload позволяет совсем не задумываться о месте объявления функций.

Rumata пишет:

Чуть ли не с самого начала предлагаю смотреть в сторону XSLT, который отобразит XML любых размеров согласно заданной разметке.

Ну чтож, желаете посмотреть - смотрите.
Чесноговоря я посмотрел и ни хрена не понял

55 (изменено: Rumata, 2012-02-05 13:36:04)

Re: HTA: XML Viewer

mozers пишет:

Данные рекомендации относятся к веб-страницам

Это требование зародилось далеко задолго до широкого распространения интернета и относится не только к веб-программированию. Далее на эту тему я не желаю говорить - так как это косвенно относится к обсуждению приложения.

mozers пишет:

Ну чтож, желаете посмотреть - смотрите.
Чесноговоря я посмотрел и ни хрена не понял

Если често - я тоже. Я думаю оно не в тему.

Не в тему, но пример очень знатный. Обратите внимание - там фреймы, три штуки!

( 2 * b ) || ! ( 2 * b )

56

Re: HTA: XML Viewer

Что касается сравнения скоростей XSLT и innerHTML+RegExp, то думаю для начала проще всего замерить скорость отображения XML в ИЕ, так как там все-таки встроенный xslt.

57 (изменено: mozers, 2012-02-06 09:58:47)

Re: HTA: XML Viewer

Ну вот, нашел простенький пример универсального шаблона, маленько его поправил. Получился такой HTA :

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style type="text/css">
	*             {font:8pt MS Shell Dlg; cursor:default;}                              /*общие определения*/
	span.text     {color:black;}                                                        /*текст пункта списка*/
	span.name     {color:buttonshadow; font-weight:bold;}                               /*имя узла*/
	span.value    {font:bold 10pt Verdana; cursor:text; margin-left:4px; color:black;}  /*текст узла*/
	span.comment  {font:bold 10pt Verdana; cursor:text; margin-left:4px; color:#999999} /*комментарий*/
	span.aname    {color:red; margin-left:4px;}                                         /*имя атрибута*/
	span.avalue   {color:#3300FC;}                                                      /*значение атрибута*/

	li            {list-style-type:circle; color:threeddarkshadow;}            /*обычный пункт списка*/
	li.hidden     {list-style-type:square; background-color:#FFFF99;}          /*выделенный пункт списка*/
</style>
<xml id="idXSL">
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
	<ul><li>
		<span class="name"><xsl:value-of select="name()" /></span>
		<xsl:apply-templates select="@*" />
		<span class="value"><xsl:apply-templates /></span>
	</li></ul>
</xsl:template>
<xsl:template match="@*">
	<span class="aname"><xsl:value-of select="name()" /></span>
	<span class="text">:</span>
	<span class="avalue"><xsl:value-of select="." /></span>
</xsl:template>
<xsl:template match="comment()">
	<span class="comment"><xsl:value-of select="." /></span>
</xsl:template>
</xsl:stylesheet>
</xml>
<script type="text/javascript">
	function LoadXML(){
		var xmlFile = 'test.xml';
		var xmlDom = new ActiveXObject('Microsoft.XMLDOM');
		xmlDom.load(xmlFile);
		var result = xmlDom.transformNode(idXSL);
		document.body.innerHTML = result;
	}
</script>
</head>
<body onload="LoadXML()"></body>
</html>

В общем - работает Скорость - офигенная! Комментарии пока выводятся не там где положено

58

Re: HTA: XML Viewer

Шаблон и вовсе можно вставить в hta в тег <xml id="...">...</xml> и вызывать по id, чтобы не грузить из внешнего файла. Можно в head, можно отдельно, где-нибудь после body. ИЕ этот тег корректно обрабатывает.
А вьюер становится всё интереснее...

59 (изменено: mozers, 2012-02-05 18:56:40)

Re: HTA: XML Viewer

Serge Yolkin пишет:

Шаблон и вовсе можно вставить в hta в тег <xml id="...">...</xml> и вызывать по id

Класс! Весь инет излазил в поисках ответа на этот вопрос. Так и не нашел. Вернулся на любимый форум - а тут он меня ждет СПАСИБО!
Щас код повыше твоего поста поправлю...

60

Re: HTA: XML Viewer

mozers пишет:

простенький пример универсального шаблона

Что я и говорил - решение есть.

mozers пишет:

Скорость не сравнивал

Теоретически, разницы большой быть не должно.

( 2 * b ) || ! ( 2 * b )

61

Re: HTA: XML Viewer

Rumata пишет:

Что я и говорил - решение есть.

За упорство в пропаганде своей идеи - СПАСИБО
Вот теперь только вывод xml-комментариев надо как то поправить... Где спецы по XSL?

62

Re: HTA: XML Viewer

Не надо ёрничать. Я предлагал нормальное решение.

mozers пишет:

вывод xml-комментариев


<xsl:template select="comment()">
Comment: <xsl:value-of select="." />
</xsl:template>
( 2 * b ) || ! ( 2 * b )

63

Re: HTA: XML Viewer

2Rumata
Я не "ерничаю". Я действительно полагаю что если бы не Ваше личное упорство, то идея обработки xml с помощью xsl была бы благополучно забыта.
А вот куда вставить приведенный Вами код, чтобы код приведенный в моем посте повыше работал, я так и не догадался

64

Re: HTA: XML Viewer

Вот. не тестировал. Проверьте на предмет ошибок. Внес некоторые исправления в тот пример, который привели Вы.


<xml id="idXSL">
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>

<xsl:template select="comment()">
<span class="comment"><xsl:value-of select="." /></span>
</xsl:template>

<xsl:template match="*">
<ul>
<li>
<span class="name"><xsl:value-of select="name()" /></span><xsl:apply-templates select="@*" />
<xsl:apply-templates />
</li>
</ul>
</xsl:template>

<xsl:template match="@*">
<span class="aname"><xsl:value-of select="name()" /></span>
<span class="text">:</span>
<span class="avalue"><xsl:value-of select="." /></span>
</xsl:template>

</xsl:stylesheet>
( 2 * b ) || ! ( 2 * b )

65

Re: HTA: XML Viewer

2Rumata
Не работает. Зачем публиковать не тестированное?

66

Re: HTA: XML Viewer

mozers пишет:

Не работает

Извините, опечатка. Все верно - в остальном код рабочий.

найдите


<xsl:template select="comment()">

Исправьте на


<xsl:template match="comment()">
( 2 * b ) || ! ( 2 * b )

67

Re: HTA: XML Viewer

2Rumata
Спасибо, работает

68

Re: HTA: XML Viewer

Еще раз исправил код в посте #57.
Включил туда немного подкорректированную xsl обработку, предложенную Rumata.
К сожалению, не все идеально:
1. Подчиненные ветки <LI> оказываются внутри <SPAN>. На отображении это никак не сказывается, но вот свертка, естественно, не работает. Надо либо править xsl (что было бы более правильным), либо - менять алгоритм обработки.
2. Раньше кружочки узлов, которые содержали подчиненные ветки и могли быть свернутыми отмечались другим цветом. Сейчас этого нет. Ломаю голову как это добавить в xsl.

69

Re: HTA: XML Viewer

Я бы предложил такую структуру документа:


<div class="tag-container">
<div class="tag"><span class="tag-name">имя тега</span> возможные атрибуты </div>
<div class="tag-content">
содержимое
</div>
</div>

Соответственно, клик внутри элемента .tag скрывает/показывает содержимое тега .tag-content.

( 2 * b ) || ! ( 2 * b )

70

Re: HTA: XML Viewer

2Rumata
Осуществить свертку с div-ами будет, конечно, проще. Но пострадает главное - наглядность отображения структуры XML.
Идеальный вариант видится как то так:

<UL>
	<LI style="color:green">
		<span class="name">NodeName</span>
		<span class="aname">AttrName</span>
		<span class="text">:</span>
		<span class="avalue">AttrValue</span>
		<span class="text">NodeText</span>
		<UL>
			<LI>
				<span class="name">NodeName</span>
				<span class="aname">AttrName</span>
				<span class="text">:</span>
				<span class="avalue">AttrValue</span>
				<span class="text">NodeText</span>
			</LI>
			<LI>
				<span class="name">NodeName</span>
				<span class="aname">AttrName</span>
				<span class="text">:</span>
				<span class="avalue">AttrValue</span>
				<span class="text">NodeText</span>
			</LI>
		</UL>
	</LI>
	<LI>
		<span class="name">NodeName</span>
		<span class="aname">AttrName</span>
		<span class="text">:</span>
		<span class="avalue">AttrValue</span>
		<span class="text">NodeText</span>
	</LI>
</UL>

где <LI style="color:green"> отмечает LI который может быть свернут.
Именно так было в предыдущих версиях. Более наглядно трудно себе представить.

71

Re: HTA: XML Viewer

Я не понимаю, как DIVы ухудшают наглядность отображения? Они (так же как и SPAN) универсальные теги, с которыми можно делать все что угодно.

( 2 * b ) || ! ( 2 * b )

72

Re: HTA: XML Viewer

2Rumata
DIV-ы будут отображены все на одном уровне, т.е. дерево превратится в простой список.
Чтобы DIV-ы сделать столь же привлекательными как LI надо добавлять шарики в начало текста и программировать отступ.
ИМХО это - сложнее чем сразу построить дерево из LI.

73 (изменено: Rumata, 2012-02-06 15:56:41)

Re: HTA: XML Viewer

А-а-а. Понятно. "Шарики" это дизайн списков по умолчанию, который включается/отключается с помощью CSS. Который, в свою очередь, применим к любому элементу страницы. Вас привлекают списки, потому-что в них изначально заданы отступы.

( 2 * b ) || ! ( 2 * b )

74 (изменено: Rumata, 2012-02-06 16:06:09)

Re: HTA: XML Viewer

Вот пример. Это черновик, который изначально состоит из отдельных файлов, которые я объединил в один для простоты тестирования. В конечном результате этот пример должен быть существенно переработан для публикации.

Я счел нужным дать некоторое пространное описание этого черновика. Если эти объяснения скучны и неинтересны, то сразу переходите к самому главному в конце.

Для отображения имени xml-тега выбран H3 из соображений, что он лучше подходит для отображения структуры (так же как Вы выбрали списки). Дизайнер из меня не очень хороший, но я предпочитаю большие буквы и много пустого пространства на странице. Поэтому не пугайтесь.
-- В CSS предусмотрены практически все необходимые правила (некоторые вставлены как пустышки). Кроме того добавлено немного рюшечек, имитирующих раскрывающиеся/схлопывающиеся подуровни в виде символов плюс/минус.
-- XSL "знает" как преобразовать текст, комментарии, xslt-инструкции, вложенные и одиночные теги и атрибуты тегов. Также "различает" теги с установленным атрибутом type="text/*".
-- JavaScript добавляет необходимую динамику - свернуть/развернуть теги.
-- HTA контейнер всего этого хозяйства.

Еще немного слов по поводу динамики. Она достигалась добавлением класса к внешнему тегу. Сокращенный пример, объясняющий действо.

Обычный вид - тег развернут


<div class="node-container">
<h3 class="node-tag">...</h3>
<div class="node-content">
...
</div>
</div>

.
Тег свернут


<div class="node-container collapsed">
<h3 class="node-tag">...</h3>
<div class="node-content">
...
</div>
</div>

.
Желаемый результат достигается за счет того, что заданы CSS-правила:

.collapsed .node-tag	{
	background-color: #ffc;
}
.collapsed .node-content	{
	display: none;
}

Первое правило меняет фоновый цвет тега, второе правило скрывает содержимое. Код управляет добавлением/удалением класса .collapsed элементу .node-container при клике внутри элемента .node-tag.


<html>
<head>
<title>XML Viewer</title>
<!--
<link type="text/css" rel="stylesheet" href="xmlview.css" />
-->
<style type="text/css">

.instruction	{
	border: 1px solid #00f;
	color: #00c;
	font-style: italic;
	font-size: 11pt;
}

.comment	{
	border: 1px solid #ccc;
	color: #999;
	font-style: italic;
	font-size: 11pt;
}

.node-container	{
	border-left: 1px solid #eee;
	font-family: Verdana, Tahoma, sans-serif;
	font-size: 11pt;
}
.node-single-tag	{
	margin: 0;
}
.node-tag	{
	border-bottom: 1px solid #eee;
	cursor: pointer;
	margin: 0;
}
.node-name	{
}
.node-text	{
}
.node-content	{
	margin: 0 0 0 20px;
}
.node-code	{
	border: 1px solid #ccc;
	background-color: #eee;
	font-size: 0.8em;
	margin: 0;
}

.attr	{
	font-size: 0.9em;
}
.attr-name	{
	color: #c00;
	font-weight: bold;
}
.attr-value	{
	color: #00c;
	font-style: italic;
}

.collapsed .node-tag	{
	background-color: #ffc;
}
.collapsed .node-content	{
	display: none;
}

.sign-closed, 
.sign-opened	{
	font-size: 12pt;
	margin-left: -15px;
	text-align: center;
	width: 15px;
}
.sign-closed	{
	display: none;
}
.collapsed .sign-closed	{
	display: inline-block;
}
.sign-opened	{
	display: inline-block;
}
.collapsed .sign-opened	{
	display: none;
}

.hidden	{
	display: none;
}

.error	{
	background-color: #ffc;
	border: 1px solid #f00;
	font-family: Verdana, Tahoma, sans-serif;
	padding: 10px;
}
.error-line	{
	color: #f00;
}

</style>
<!--
<script type="text/javascript" src="xmlview.js"></script>
-->
<script type="text/javascript"><!--//--><![CDATA[//><!--

var Element = {
	/**
	 * Checks that an element has a provided className
	 */
	classExists: function(element, className)
	{
		return this.RE(className).test(element.className);
	}, 
	/**
	 * Creates the regular expression to check that 
	 * a className is defined for an element and 
	 * remove an existing one from an element
	 */
	RE: function(className)
	{
		return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
	}, 
	/**
	 * Adds a className to an element
	 */
	addClass: function(element, className)
	{
		if ( ! this.classExists(element, className) ) {
			element.className += ' ' + className;
		}
		return element;
	}, 
	/**
	 * Removes a classname
	 */
	removeClass: function(element, className)
	{
		className = element.className.replace(this.RE(className), ' ');
		if ( className != element.className ) {
			element.className = className;
		}
		return element;
	}, 
	/**
	 * Toggles (turn on/turn off) a className
	 */
	toggleClass: function(element, className)
	{
		if ( this.classExists(element, className) ) {
			this.removeClass(element, className);
		} else {
			this.addClass(element, className);
		}
		return element;
	}
};

var XMLView = {
	/**
	 * Loads and validate a xml-file
	 */
	loadXml: function(filename, async, onreadystatechange)
	{
		var doc = new ActiveXObject("Msxml2.DOMDocument");
		doc.async = async;
		if ( typeof onreadystatechange == 'function' ) {
			doc.onreadystatechange = onreadystatechange;
		}
		doc.load(filename);
		return doc;
	}, 
	/**
	 * Loads an input xml-file, shows errors if they occur
	 *
	 * loader is callback-function that should return an xml-document
	 *
	 * onerror is callback function, handler of parsing errors
	 */
	loadSafely: function(loader, onerror)
	{
		if ( typeof loader != 'function' ) {
			throw new TypeError();
		}

		var doc = loader(this);
		if ( ! doc ) {
			return;
		}

		var err = doc.parseError;

		if ( err.errorCode == 0 ) {
			return doc;
		}

		if ( typeof onerror == 'function' ) {
			onerror(err);
		}
	}, 
	/**
	 * Loads an input xml-file and the predefined xsl-file
	 * and transforms a xml-file accordingly xsl
	 *
	 * xmlLoader and xslLoader are callback-functions that 
	 * should return xml-documents
	 *
	 * onerror is callback function, handler of parsing errors
	 */
	transform: function(xmlLoader, xslLoader, onerror)
	{
		var xml = this.loadSafely(xmlLoader, onerror);
		if ( ! xml ) {
			return;
		}

		var xsl = this.loadSafely(xslLoader, onerror);
		if ( ! xsl ) {
			return;
		}

		return xml.transformNode(xsl);
	}, 

	/**
	 * The main routine
	 *
	 * Loads the predefined xsl-file
	 * Loads an input xml-file
	 * Transform an input file
	 * Outputs the result or details on error to a html page
	 *
	 * element is a reference to a html-element that is provided
	 * when the method is called
	 *
	 * xmlLoader and xslLoader are callback-functions that 
	 * should return well-fromed xml-files
	 *
	 * onerror is callback function, handler of parsing errors
	 */
	init: function(element, xmlLoader, xslLoader, onerror)
	{
		var html;

		if ( element ) {
			html = this.transform(xmlLoader, xslLoader, onerror);
		}

		if ( html ) {
			element.innerHTML = html;
		}

		document.onmousedown = function(e)
		{
			e = e || event;
			var target = e.target || e.srcElement;

			// Looking for the nearest node-tag
			while ( target && (target.className || '').indexOf('node-tag') == -1 ) {
				target = target.parentNode;
			}

			if ( ! target ) {
				return;
			}

			// Perform toggle (turn on/turn off)
			Element.toggleClass(target.parentNode, 'collapsed');
		};
	}
};

//--><!]]></script>
<script type="text/javascript"><!--//--><![CDATA[//><!--

window.onload = function()
{
	var html_entity_encode = function(value)
	{
		var div = document.createElement('div');
		var text = document.createTextNode(value);
		div.appendChild(text);
		return div.innerHTML.replace(/"/g, '&quot;').replace(/'/g, ''');
	};

	var xmlfile;
//	var xslfile = 'xmlview.xsl';

	XMLView.init(
		// the reference to the xml-container
		document.getElementById('xml-container'), 

		// xml-file loader
		function(XMLView)
		{
			// Load a file using type=file input
			var f = document.getElementById('openFile');
			f.click();

			xmlfile = f.value;
			if ( ! xmlfile ) {
				return;
			}

			document.title += ' :: ' + xmlfile;

			return XMLView.loadXml(xmlfile);
		}, 

		// xsl-file loader
		function(XMLView)
		{
			return document.getElementById('xslDocument');
//			return XMLView.loadXml(xslfile);
		}, 

		// parsing error handler
		function(err)
		{
			Element.removeClass(document.getElementById('error-container'), 'hidden');

			document.getElementById('error-url').innerHTML = err.url;
			document.getElementById('error-reason').innerHTML = err.reason;
			document.getElementById('error-line').innerHTML = err.line;
			document.getElementById('error-linepos').innerHTML = err.linepos;

			document.getElementById('error-srcText').innerHTML = html_entity_encode(err.srcText);
			document.getElementById('error-pointer').innerHTML = new Array(err.linepos).join('-') + '^';
		}
	);
};

//--><!]]></script>
</head>
<body>

<div id="xml-container"></div>

<div class="error hidden" id="error-container">
<b>URL: </b><span id="error-url"></span><br />
<b>Error: </b><span id="error-reason"></span><br />
<b>Line: </b><span id="error-line"></span><br />
<b>Position: </b><span id="error-linepos"></span><br />
<br />
<code class="error-line" id="error-srcText"></code><br />
<code class="error-line" id="error-pointer"></code>
</div>

<div class="hidden">
<input type="file" id="openFile" />
</div>

</body>
<xml id="xslDocument">
<!--
<?xml version="1.0"?>
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" indent="no" />

<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>

<xsl:template match="processing-instruction()">
<div class="instruction"><xsl:value-of select="name()"/><xsl:text> </xsl:text><xsl:value-of select="."/></div>
</xsl:template>

<xsl:template match="comment()">
<div class="comment"><xsl:value-of select="." /></div>
</xsl:template>

<xsl:template match="text()">
<span class="node-text"><xsl:value-of select="." /></span>
</xsl:template>

<xsl:template match="*">
<div class="node-container">
<h3 class="node-single-tag"><span class="node-name"><xsl:value-of select="name()" /></span><xsl:apply-templates select="@*" /></h3>
</div>
</xsl:template>

<xsl:template match="*[node()]">
<div class="node-container">
<h3 class="node-tag">
<span class="sign-opened">-</span><span class="sign-closed">+</span>
<span class="node-name"><xsl:value-of select="name()" /></span><xsl:apply-templates select="@*" /></h3>
<div class="node-content">
<xsl:choose>
<xsl:when test="starts-with(@type,'text/')">
<pre class="node-code"><xsl:value-of select="." /></pre>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</div>
</div>
</xsl:template>

<xsl:template match="@*">
<xsl:text> </xsl:text><span class="attr"><code class="attr-name"><xsl:value-of select="name()" /></code><xsl:text>=</xsl:text><code class="attr-value"><xsl:value-of select="." /></code></span>
</xsl:template>

</xsl:stylesheet>
</xml>
</html>
( 2 * b ) || ! ( 2 * b )

75

Re: HTA: XML Viewer

По сути переделано ВСЕ.
А вообще - КЛАСС! Мне очень нравится
Есть, конечно, мелкие вопросы... Но лучше я их оставлю "на потом".
Меня больше интересует как бы сделать так, чтобы содержимое узла отображалось в одной строке с именем и атрибутами (как было раньше), а не занимало отдельную под-строку. И раньше эта проблема решалась непросто и сейчас, видимо, придется покумекать...

76

Re: HTA: XML Viewer

mozers пишет:

как бы сделать так, чтобы содержимое узла отображалось в одной строке с именем и атрибутами

Я тоже думал над этим (когда хотел представить свое видение задачи). Надо отказаться от списков UL/LI и полностью перейти на SPAN - строковым элементам. Либбо изменить отображение элементов с помощью CSS. Это решаемо - ведь МСИЕ показывает текстовое содержимое тега в той же строке что и имя тега. Мозилла в отличие от МСИЕ отображает текст в отдельной строке.

mozers пишет:

Мне очень нравится

Спасибо.

mozers пишет:

вопросы

К сожалению я мало документировал код, поэтому многое со временем забудется. Так задавайте свои вопросы сразу. Возможно они кое-что мне помогут прояснить. Я заложил некоторые основы для расширяемости, но пока я не знаю в каком направлении двигаться дальше - то ли расширять существующий код, то ли полностью переписать его.

( 2 * b ) || ! ( 2 * b )

77

Re: HTA: XML Viewer

2Rumata
Я просил помощи только с XSL. Вы же по сути выложили совершенно иную программу.
Мне очень нравятся использованные в ней решения, и я обязательно буду их использовать в XMLViewer (конечно, не забыв упомянуть их автора). Но использовать код целиком (пусть даже модифицированный) я не буду.
У меня свое видение результата и способов его достижения. У Вас - свое.
В Вашем коде мне многое непонятно. Например, зачем нужны ф-ции подмены классов когда можно запросто присвоить любому элементу нужный класс obj.className='myclass'? Зачем нужны постоянные document.getElementById() когда можно просто обратиться к элементу, указав его id? Зачем понатыкана куча ненужных кросс-браузерных проверок, ведь HTA работает только на движке IE? Продолжать задавать вопросы можно долго...
Нет уж, лучше я вырву из Вашего кода то, что мне ОЧЕНЬ понравилось и продолжу свой путь

78

Re: HTA: XML Viewer

mozers пишет:

У меня свое видение результата и способов его достижения. У Вас - свое

И это естественно. )))

mozers пишет:

зачем нужны ф-ции подмены классов когда можно запросто присвоить любому элементу нужный класс obj.className='myclass'?

Подмена класса, или точнее добавление/удаление определенного класса. Каждый класс содержит определенный набор правил. Соответственно, управляя классами над заданным элементом легко манипулировать внешним видом элемента. А функции необходимы для унификации обращения с произвольными классами произвольных элементов.

mozers пишет:

постоянные document.getElementById() когда можно просто обратиться к элементу, указав его id?

Если обращение к элементу одноразовое, например Element.removeClass(document.getElementById('error-container'), 'hidden'); и далее по тексту, то и создание переменной избыточно. А использование функции вместо прямого обращения по id - это старые привычки, унаследованные от веб-программирования. Кстати, неплохие привычки. И еще. Я уже не помню, но кажется в одном из браузеров не рекомендуется создавать переменные, одноименные существующим тегам.

mozers пишет:

Зачем понатыкана куча ненужных кросс-браузерных проверок

А вот здесь я требую конкретных примеров кучи.

mozers пишет:

вырву из Вашего кода то, что мне ОЧЕНЬ понравилось и продолжу свой путь

Дерзайте )))

( 2 * b ) || ! ( 2 * b )

79

Re: HTA: XML Viewer

Черт меня дернул в посте #68 пожаловаться на то, что "подчиненные ветки <LI> оказываются внутри <SPAN>".
Виноват, дурак, подумать надо было сначала!
На поверку оказалось, что это - не беда, а - великая радость!
Т.е. если отказаться от прежнего алгоритма с последовательным перебором всех подчиненных веток, а скрывать все их целиком (как в варианте Rumata), то можно осуществить свертку одной строкой: objSPAN.style.display = (hide) ? 'none' : ''; без всяких ф-ций и прочих заморочек!
Так, же,одной строкой oLI.className = (hide) ? 'hidden' : ''; осуществляется подсветка свернутого узла.
В общем код получился очень простой и понятный.
Что же касается скорости, то, по моим измерениям, использование XSL обработки увеличивает ее в 1,5-2 раза.
В, общем все последние изменения зафиксированы тут.
Последний zip.

2Rumata
1. Ваше авторство зафиксировал. Если что не так - только скажите - поправлю.
2. Как видите, прекрасно обошелся без всяких "классовых" ф-ций и других "наворотов".
3. Простите, я неверно выразился, обобщив одним словом "кроссбраузерность" все конструкции, нужные только там где неизвестна версия браузера. Всякие там
<script type="text/javascript"><!--//--><![CDATA[//><!--
<!--
<?xml version="1.0"?>
-->
e = e || event;
var target = e.target || e.srcElement;
и т.п.

80

Re: HTA: XML Viewer

Огромная работа проделана. Поздравляю )))

Кроссбраузерность явно представлена только в строках

e = e || event;
var target = e.target || e.srcElement;

Остальные проверки - чистые алгоритмические проверки, не связанные с кроссбраузерностью. Вычурная срока <!--//--><![CDATA[//><!--... Видимо она как-то связана поддержкой старых браузеров -- я не вдавался в ее магию, а использовал чтобы парсер МСИЕ нормально работал и XML Viewer воспринял код приложения как валидный XML.

( 2 * b ) || ! ( 2 * b )

81 (изменено: Rumata, 2013-02-21 06:18:07)

Re: HTA: XML Viewer

Прошел год с небольшим и я снова вернулся к теме обработки XML. Интерес возник по причине моего увлечения электронной читалкой и, своего рода, каталогизации коллекции электронных книг. В первую очередь было интересно как автоматизировать процесс переименования и сортировки книг.

В связи с этим узнал ближе XPath. Это язык запросов к элементам XML в XSL-преобразованиях. Достаточно прост и элегантен. Было бы интересно попробовать реализовать отображение XPath-запросов к заданным элементам XML-документа. Список запросов можно генерировать однократно для всех объектов (элементов или их атрибутов) в процессе загрузки файла в XML Viewer либо отображать отдельный XPath-запрос по наведению указателя мыши на объект.

( 2 * b ) || ! ( 2 * b )

82

Re: HTA: XML Viewer

OFF: Насчёт — «прост», я бы поспорил .

83 (изменено: Rumata, 2013-02-21 15:17:21)

Re: HTA: XML Viewer

alexii
К XPath я пришел через несколько собственных попыток понимания XSLT. По сравнению со вторым - первый прост. Вот другой вопрос - как полно он поддерживается в JScript/VBS. У меня не получилось поиграться с осями, а кроме функции text() других просто не признает.

( 2 * b ) || ! ( 2 * b )

84

Re: HTA: XML Viewer

К XPath я пришел через несколько собственных попыток понимания XSLT. По сравнению со вторым - первый прост.

А… Ну, так — да, согласен.

85

Re: HTA: XML Viewer

А не подскажете ли, как с помощью xslt преобразования можно обрабатывать текстовые ноды по отдельности? Ну, для примера: из xml

<root>
  <tag1>
    текст1
    <tag2>
      текст2
      <tag3/>
      текст3
    </tag2>
  </tag1>
  текст4
</root>

получить html

<p>текст1</p>
<p>текст2</p>
<p>текст3</p>
<p>текст4</p>

причём, в общем случае (без привязки к именам тэгов и структуре дерева).

86 (изменено: Rumata, 2013-07-14 00:35:33)

Re: HTA: XML Viewer

Serge Yolkin

Быстренько, на коленке написал. Подходит? Если требуются более сложные преобразования, то надо углубляться в тему.


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="//*/text()">
<xsl:if test="normalize-space() != ''">
<p><xsl:value-of select="normalize-space()" /></p>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

( 2 * b ) || ! ( 2 * b )

87 (изменено: Serge Yolkin, 2013-07-14 01:53:14)

Re: HTA: XML Viewer

Спасибо, Rumata, затык пройден, буду мудрить дальше.

[Off]
Вообще-то, жаль, что тема XSL на форуме не раскрыта. И в интернете материалов немного. Если не считать перепечатки одних и тех же статей. Собственно, все примеры сводятся к преобразованию заранее известного и хорошо структурированного XML, а более универсальные решения - на вес золота.

Если кому интересно, случайно обнаружил забавный утиль по данной теме (искал, как раз, примеры)

[/Off]

88

Re: HTA: XML Viewer

Serge Yolkin
XML/XSL: Обработка всех текстовых узлов всех тегов

Эту задачу тоже можно решить. Сейчас я занят. В будущем отвечу в той теме. Дам разъяснения того кода. Если смогу (время и мое понимание) - помогу решить и эту задачу.

( 2 * b ) || ! ( 2 * b )