Хитрое XSLT-преобразование - PullRequest
2 голосов
/ 15 октября 2011

Предположим, что дерево XML состоит из пар меток и элементов, каждая из которых содержит разметку, требующую преобразования:

<list>
   <label>ABC<ptr target="#note-1"/></label>
   <item><ref type="link">123</ref></item>
   <label>DEF<ptr target="#note-2"/></label>
   <item><ref type="link">456</ref></item>
   ...
</list>

(Примечание: разметка внутри элементов <label> и <item>просто пример. Эти элементы могут иметь произвольное количество разметки, содержащейся в них. Таким образом, эта вложенная разметка будет обрабатываться правилами шаблонов. Использование строковых функций XSL и т. д. для обработки этой вложенной разметки не являетсяидеальное решение, так как число возможных тегов велико.)

Предположим, что цель состоит в том, чтобы преобразовать это в неупорядоченный список HTML, например:

<ul>
   <li>ABC<sup>1</sup> <a href="link1.html">123</a></li>
   <li>DEF<sup>2</sup> <a href="link2.html">456</a></li>
   ...
</ul>

Я пыталсячтобы сопоставить пары узлов <label><item> с предыдущей осью :: sibling, например,

   <xsl:template match="list[@type='index']/item[preceding-sibling::label]" >
    <li><xsl:value-of select="./preceding-sibling::label[1]"/> <xsl:apply-templates/></li>
   </xsl:template>

Но мой вывод выдает содержимое <label> дважды: один раз перед элементом <li> (правильно преобразованным)и снова внутри элемента <li> (без преобразования), например:

  <ul>
     ABC<sup>1</sup>
     <li>ABC <a href="link1.html">123</a></li>
     DEF<sup>2</sup>
     <li>DEF <a href="link2.html">456</a></li>
     ...
  </ul>

Я понимаю, что содержимое <label> внутри <li> не преобразуется, потому что я использую <xsl:value-of>.Я просто пытаюсь проиллюстрировать цель, которую я пытаюсь достичь, чтобы получить содержимое <label> и <item> внутри <li>.

Если я добавлюследующий шаблон для подавления второго экземпляра содержимого из элемента <label>:

<xsl:template match="list[@type='index']/label"></xsl:template>

, тогда избыточный набор содержимого из <label> удаляется, но не правильный.Например,

<ul>
     <li>ABC <a href="link1.html">123</a></li>
     <li>DEF <a href="link2.html">456</a></li>
     ...
  </ul>

Итак, мой вопрос: как мне получить содержимое из <label> и <item> в один элемент <li>, в то же время обрабатывая это содержимое другимишаблоны в моей таблице стилей?

1 Ответ

1 голос
/ 15 октября 2011

Это довольно просто сделать в XSLT :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="list">
  <ul>
    <xsl:apply-templates select="label"/>
  </ul>
 </xsl:template>
 <xsl:template match="label">
  <li>
   <xsl:value-of select="."/>

   <xsl:variable name="vPos" select=
       "substring-after(ptr/@target, '#note-')"/>
   <sup>
     <xsl:value-of select="$vPos"/>
   </sup>
   <xsl:apply-templates select=
      "following-sibling::*[1][self::item]">
    <xsl:with-param name="pPos" select="$vPos"/>
   </xsl:apply-templates>
  </li>
 </xsl:template>

 <xsl:template match="item">
  <xsl:param name="pPos"/>
   <a href="{@type}{$pPos}.html">
     <xsl:value-of select="."/>
   </a>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному XML-документу (исправлено, чтобы оно было правильно сформировано):

<list>
   <label>ABC<ptr target="#note-1"/></label>
   <item><ref type="link">123</ref></item>
   <label>DEF<ptr target="#note-2"/></label>
   <item><ref type="link">456</ref></item>
</list>

желаемый, правильный результат получается :

<ul>
   <li>ABC<sup>1</sup>
      <a href="1.html">123</a>
   </li>
   <li>DEF<sup>2</sup>
      <a href="2.html">456</a>
   </li>
</ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...