Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > XML, XSL > Непонятки с XPath и Position


Автор: SelenIT 7.4.2007, 20:56
Продолжение недавней моей http://forum.vingrad.ru/topic-144896.html о разворачивании рекрсивного дерева одноименных элементов в плоский список.

Получить плоскую структуру удалось, но теперь еще нужно для каждой исходной ноды получить XPath-путь к ней. Предупреждая вопросы, что за изврат я делаю - это JS-меню для навигации по фактически XML-ной базе данных со вложенной структурой, по клику на пункты будут выбираться определенные подэлементы соответствующих нод.

При попытке получить желаемое, преобразуя файл
Код

<elem id="e1">
     <elem id="e2"/>
     <elem id="e3">
          <elem id="e8"/>
          <elem id="e9"/>
          <elem id="e10"/>
          <elem id="e11"/>
     </elem>

     <elem id="e5"/>
     <elem id="e6"/>
     <elem id="e7">
          <elem id="e12"/>
          <elem id="e13"/>
          <elem id="e14"/>
          <elem id="e15"/>
     </elem>
</elem>

с помощью такого XSL:
Код

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

<xsl:template match="elem">
    <xsl:param name="path"/>
    <xsl:element name="div">
    <xsl:value-of select="@id" />: <xsl:value-of select="$path"/>/elem[<xsl:value-of select="position()"/>]
    </xsl:element>
    <xsl:apply-templates select="./elem">
    <xsl:with-param name="path"><xsl:value-of select="$path"/>/elem[<xsl:value-of select="position()"/>]</xsl:with-param>
    </xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>

я получил следующее:
Код

e1: /elem[2]
e2: /elem[2]/elem[1]
e3: /elem[2]/elem[2]
e8: /elem[2]/elem[2]/elem[1]
e9: /elem[2]/elem[2]/elem[2]
e10: /elem[2]/elem[2]/elem[3]
e11: /elem[2]/elem[2]/elem[4]
e5: /elem[2]/elem[3]
e6: /elem[2]/elem[4]
e7: /elem[2]/elem[5]
e12: /elem[2]/elem[5]/elem[1]
e13: /elem[2]/elem[5]/elem[2]
e14: /elem[2]/elem[5]/elem[3]
e15: /elem[2]/elem[5]/elem[4]

Никак не могу взять в толк, почему корневой элемент у меня вдруг везде оказался обозначен как /elem[2]? И что вообще я делаю неправильно?

Автор: Exception 8.4.2007, 16:46
Код

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="/">
    <xsl:apply-templates select="elem" />
</xsl:template>

<xsl:template match="elem">
    <xsl:param name="path"/>
    <xsl:element name="div">
    <xsl:value-of select="@id" />: <xsl:value-of select="$path"/>/elem[<xsl:value-of select="position()"/>]
    </xsl:element>
    <xsl:apply-templates select="./elem">
    <xsl:with-param name="path"><xsl:value-of select="$path"/>/elem[<xsl:value-of select="position()"/>]</xsl:with-param>
    </xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>

Автор: SelenIT 8.4.2007, 18:11
Exception, еще раз спасибо, благодаря подсказкам решил свою задачу!

А все-таки, почему без отдельного
Код

<xsl:template match="/">
    <xsl:apply-templates select="elem" />
</xsl:template>
корневая нода для position() оказывалась второй, а не первой?

Автор: JVM 9.4.2007, 13:54
А у меня с первым xsl получается
Код

<div xmlns="http://www.w3.org/1999/xhtml">e1: /elem[1]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e2: /elem[1]/elem[1]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e3: /elem[1]/elem[2]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e8: /elem[1]/elem[2]/elem[1]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e9: /elem[1]/elem[2]/elem[2]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e10: /elem[1]/elem[2]/elem[3]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e11: /elem[1]/elem[2]/elem[4]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e5: /elem[1]/elem[3]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e6: /elem[1]/elem[4]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e7: /elem[1]/elem[5]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e12: /elem[1]/elem[5]/elem[1]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e13: /elem[1]/elem[5]/elem[2]
  </div><div xmlns="http://www.w3.org/1999/xhtml">e14: /elem[1]/elem[5]/elem[3]
    </div><div xmlns="http://www.w3.org/1999/xhtml">e15: /elem[1]/elem[5]/elem[4]
</div>

Использую xsltproc.

Автор: Exception 9.4.2007, 13:55
Интересно smile . Я тестил в FF.

Автор: SelenIT 9.4.2007, 15:41
Я тоже тестил в браузерах (FF2 и IE6). Вообще-то, на самом деле нужно мне это преобразование только для IE, под Microsoft.XMLDOM. Но то, что такие разные браузеры сходятся в неожиданном результате, наводит на мысль, что вряд ли он расходится со стандартом (который я пока, увы, довольно слабо понимаю)... Заранее благодарен за ликбез!

Автор: JVM 9.4.2007, 17:28
Если вы тестили через IE и FF, то все понятно почему у вас такой результат.
У вас наверняка в исходном xml есть строчка подобная этой
Код

<?xml-stylesheet type="text/xml" href="position.xsl" ?>

так вот эта инструкция и есть ваш первый элемент - а elem уже второй.
Чтобы управлять этим процессом рекомендую использовать <xsl:number>

Используйте процессоры, а не проузеры smile 

Автор: SelenIT 9.4.2007, 17:36
Цитата(JVM @  9.4.2007,  17:28 Найти цитируемый пост)
наверняка в исходном xml есть строчка подобная этой

Точно! Есть такая строчка. Вот, значит, где обака порылась... сроду бы не подумал. JVM, огромное спасибо за разъяснение!

Цитата(JVM @  9.4.2007,  17:28 Найти цитируемый пост)
Используйте процессоры, а не проузеры

Ну задача передо мной стоит - дело должно происходить на клиенте, не я ее ставил... А чем, собственно, Microsoft.XMLDOM не процессор?

Автор: Exception 10.4.2007, 00:08
Цитата(SelenIT @  9.4.2007,  18:36 Найти цитируемый пост)
Ну задача передо мной стоит - дело должно происходить на клиенте, не я ее ставил... А чем, собственно, Microsoft.XMLDOM не процессор? 


Имеется в виду, чтобы XSL применялся через вызов метода процессора. а не из-за обработки браузером инструкции xml-stylesheet.

Автор: JVM 10.4.2007, 08:38
Цитата(SelenIT @  9.4.2007,  17:36 Найти цитируемый пост)
дело должно происходить на клиенте
А есть ли примеры такого подхода? Хотел бы посмотреть.

Дело в том что мне не понятны мотивы, которые перевешивают в пользу обработки xml на стороне клиента, а не на стороне сервера.

Автор: Exception 10.4.2007, 12:56
Цитата(JVM @  10.4.2007,  09:38 Найти цитируемый пост)
А есть ли примеры такого подхода? Хотел бы посмотреть.


Например. XML загружается с сервера асинхронно.

Автор: JVM 10.4.2007, 17:29
Exception, объясни поподробнее что это значит и какие дает преимущества.

Автор: Exception 10.4.2007, 18:04
Скажем, мы реализуем autocomplete для текстбокса как в Google Suggest. В зависимости от запроса мы грузим с сервера XML с вариантами автозаполнения и динамически применяем к нему XSL. Грузить уже преобразованную версию слишком накладно, да и код логики сервера мешается с кодом отображения на клиенте.

Автор: JVM 11.4.2007, 09:16
Почитал про Google Suggest, но так и не нашел, где речь идет об XSL. XML возвращается smile , но насколько я понимаю обрабатывает его JavaScript. Где можно почитать об испоьзовании XSL или как убедиться в этом?

Автор: Exception 11.4.2007, 15:48
Цитата(JVM @  11.4.2007,  10:16 Найти цитируемый пост)
XML возвращается


Цитата(JVM @  11.4.2007,  10:16 Найти цитируемый пост)
обрабатывает его JavaScript


А я о чём? К полученному XML применяется XSL и мы получаем готовый HTML-код.

http://goog-ajaxslt.sourceforge.net/

Автор: JVM 11.4.2007, 16:54
Запутался smile Искал обработку xml и связывал это с каким-нибудь xslt-процессором.

Насколько понимаю это все таки не xslt-процессор, а просто некоторый обработчик xml имеющий узкое использование?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)