Добавление тегов ‹span› ко всем текстовым узлам между настраиваемыми самозакрывающимися тегами

У меня есть пара настраиваемых самозакрывающихся тегов s1 и s2, определенных в пространстве имен x в моем xhtml. Для каждой пары тегов s1, s2 с одинаковым идентификатором я хочу добавить теги span ко всем текстовым узлам между ними. Каждая пара тегов s1, s2 имеет уникальный идентификатор. Я ищу решение на основе XSL для того же. Я использую саксонский Java-процессор для XSL.

Пример ввода:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
  This is my heading 
</h1> 
<p> 
  Sample content Some text here. Some content here. 
</p> 
<p> 
   Here you go. 
</p> 
</body> 
</html> 

Пример вывода:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
  This <span class="spanClass" id="1">is my</span>heading 
</h1> 
<p> 
  Sample content <span class="spanClass" id="2">Some text here. Some content here.</span> 
</p> 
<p> 
   <span class="spanClass" id="3">Here you</span>go. 
</p> 
</body> 
</html> 

person Community    schedule 21.04.2010    source источник
comment
Пожалуйста, переформатируйте свой код, его трудно читать.   -  person topskip    schedule 21.04.2010
comment
На самом деле, прочитать код по-прежнему практически невозможно. Пожалуйста, отформатируйте его как блок кода, то есть все с отступом в четыре пробела (см. Справку по форматированию). См., Например, stackoverflow.com/questions/2685250/xsl-numeric-generate -id   -  person topskip    schedule 21.04.2010
comment
Форматирование сейчас идеальное, понимание (с моей стороны) тоже, но не могу решить это прямо сейчас   -  person topskip    schedule 21.04.2010
comment
Хороший вопрос (+1). См. Мой ответ для простого решения. :)   -  person Dimitre Novatchev    schedule 22.04.2010
comment
Я удалил другой похожий пост и отредактировал этот, так что теперь мой вопрос ясен. Спасибо.   -  person Rachel    schedule 23.04.2010


Ответы (2)


Это преобразование:

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

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="text()[(preceding::s1 | preceding::s2)[last()][self::s1]]">
  <span class="spanClass" id="{generate-id()}">
   <xsl:copy-of select="."/>
  </span>
 </xsl:template>

 <xsl:template match="s1|s2"/>
</xsl:stylesheet>

при применении к исходному XML-документу (исправлено на правильно сформированное):

<a>
  <b>Some <s1 id="1" />text here</b>
  <c>Some <s2 id="1"/>more text <s1 id="2"/> here</c>
  <d>More data</d>
  <e>Some <s2 id="2" />more data</e>
</a>

производит желаемый результат:

<a>
  <b>Some <span class="spanClass" id="IDANI2QB">text here</span></b><span class="spanClass" id="IDAOI2QB">
  </span><c><span class="spanClass" id="IDAQI2QB">Some </span>more text <span class="spanClass" id="IDAWI2QB"> here</span></c><span class="spanClass" id="IDAXI2QB">
  </span><d><span class="spanClass" id="IDAYI2QBIDAYI2QB">More data</span></d><span class="spanClass" id="IDAZI2QB">
  </span><e><span class="spanClass" id="IDA1I2QB">Some </span>more data</e>
</a>
person Dimitre Novatchev    schedule 21.04.2010
comment
Кстати, можете ли вы объяснить, почему один и тот же узел имеет более длинный, чем обычно, идентификатор в наших результатах? - person Tomalak; 22.04.2010
comment
@Rachel: Пожалуйста, обновите свой вопрос более точным определением проблемы или задайте другой вопрос. Урок в том, чтобы подумать, прежде чем задавать вопрос, как лучше всего определить проблему. - person Dimitre Novatchev; 22.04.2010
comment
@Tomalak: значение generate-id () зависит от реализации. Здесь я использовал MSXML4. Использование Saxon, вероятно, приведет к созданию совершенно разных идентификаторов. - person Dimitre Novatchev; 22.04.2010
comment
Я ожидал, что вы будете использовать MSXML из-за подобия (я использую msxsl.exe большую часть времени), но я никогда не видел сгенерированного идентификатора с двойной длиной, и я подозревал, что вы знаете условие, которое запускает это. - person Tomalak; 22.04.2010

РЕДАКТИРОВАТЬ: измененный ответ для работы с добавленным вами образцом XHTML.

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:x="http://www.w3.org/1999/xhtml" 
  xmlns="http://www.w3.org/1999/xhtml" 
  exclude-result-prefixes="x"
>
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" />

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()[normalize-space()]">
    <xsl:choose>
      <xsl:when test="preceding::x:s1[1][
        not(following::x:s2[1][
          following::text()[generate-id() = generate-id(current())]
        ])
      ]">
        <span class="spanClass" id="{generate-id()}">
          <xsl:copy-of select="." />
        </span>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="x:s1|x:s2" />

</xsl:stylesheet>

Результат (разрывы строк / отступы для удобочитаемости):

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>This is my title</title>
  </head>
  <body>
    <h1 align="center">
      This <span class="spanClass" id="IDATA2Q">is my</span>heading
    </h1>
    <p>
      Sample content <span class="spanClass" id="IDA2A2Q">Some text here. Some content here.</span>
    </p>
    <p>
       <span class="spanClass" id="IDA5A2Q">Here you</span>go.
    </p>
  </body>
</html>
person Tomalak    schedule 21.04.2010
comment
@Rachel: Именно по этой причине вам следует не придумывать XML, а использовать реальный пример. Легко упустить важные детали при составлении материала, чтобы упростить вопрос, что приводит к двойной работе для всех. Какая трата, тебе не кажется? - person Tomalak; 22.04.2010
comment
Ваше решение тоже неплохое. +1 от меня :) - person Dimitre Novatchev; 22.04.2010
comment
@Rachel: Просто измените свой XML-пример, чтобы он отражал реальность. - person Tomalak; 22.04.2010
comment
@Dimitre: Спасибо. Я очень гордился выражением XPath, пока вам не пришлось подойти и уничтожить мой подход. ;-) - person Tomalak; 22.04.2010
comment
@ Рэйчел: См. Мой измененный ответ. Однако я не совсем уверен, что ваш образец действительно отражает реальность. В XHTML нет элементов <s1> или <s2>, поэтому ваш входной документ недействителен. Может ли быть, что эти двое находятся в другом пространстве имен? - person Tomalak; 22.04.2010
comment
@Tomalak: изменение, которое я увидел в XSL, - это добавление пространства имен по сравнению с предыдущим. Это имеет большое значение? - person Rachel; 22.04.2010
comment
@ Рэйчел: Серьезно, от этого младенец Иисус плачет. Я просил вас включить в ваш вопрос полный, хорошо сформированный и реальный образец вместо того, что вы только что придумали. Вы изменили свой вопрос только для того, чтобы сказать мне сейчас, что новый XML в вашем вопросе может еще не быть реальным и что вы могли забыть некоторые пространства имен. Я не собираюсь изменять свой ответ в третий раз только потому, что вы все время меняете вопрос в воздухе. В следующий раз примите решение, прежде чем задать здесь вопрос, потому что такой итеративный подход - невероятная трата времени. Прости. - person Tomalak; 22.04.2010
comment
@Rachel: Я читал, что пытаюсь проверить выполнимость, поскольку я даже не уверен, собираемся ли мы делать это с помощью XSLT или вообще, но давайте спросим некоторых парней в Интернете и посмотрим, что они придумают с участием. Извините, неправильное отношение. Теперь я внес в свой ответ то последнее изменение, которого на самом деле хотел избежать. Он работает с образцом, который вы предоставили, и дает желаемый результат. Пожалуйста, не публикуйте более подробную информацию или разъяснения, если этот ответ вас не устраивает, я не могу вам помочь. - person Tomalak; 22.04.2010
comment
Благодарим за уделенное время и приносим извинения за доставленные неудобства. - person Rachel; 23.04.2010