Использование XSLT для изменения окружающих данных на основе пустого тега - PullRequest
2 голосов
/ 25 августа 2010

В процессе создания таблицы стилей для преобразования старых транскрипций LoC книг, в которых для форматирования использовался устаревший DTD SGML, я столкнулся с препятствием в следующей ситуации:

В преобразованных файлах XML есть несколько строк текста, подобных следующему:

<p> Text on left <hsep></hsep> Text on right </p>

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

<p> Text on left <span class="right">Text on right</span> </p>

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

<p> Text a <em> Text b <hsep></hsep> Text c </em> </p>

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

<p> <em> Text a Text b <hsep></hsep> Text c </em> </p>

Я могу придумать сложные, ужасные способы сделать это с помощью регулярных выражений, но я надеюсь, что есть не ужасный способ.

Ответы [ 2 ]

2 голосов
/ 25 августа 2010

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

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="hsep">
        <span class="right">
            <xsl:apply-templates select="following-sibling::node()[1]"/>
        </span>
    </xsl:template>
</xsl:stylesheet>

С вводом Димитра:

<html>
  <p> Text a <em> Text b <hsep></hsep> Text c </em> </p>
  <p> <em> Text a Text b <hsep></hsep> Text c </em> </p>
</html>

Выход:

<html>
<p> Text a <em> Text b <span class="right"> Text c </span></em></p>
<p><em> Text a Text b <span class="right"> Text c </span></em></p>
</html>

Примечание : В режиме out вы можете объявить правило один раз для элементов, предшествующих или следующих hsep.

1 голос
/ 25 августа 2010

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

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

 <xsl:template match="hsep">
  <span class="right">
   <xsl:apply-templates mode="copy"
        select="following-sibling::node()"/>
  </span>
 </xsl:template>

 <xsl:template match="node()[preceding-sibling::hsep]"/>

 <xsl:template mode="copy"
  match="node()[preceding-sibling::hsep]">

  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

применительно к этому документу :

<html>
  <p> Text a <em> Text b <hsep></hsep> Text c </em> </p>
  <p> <em> Text a Text b <hsep></hsep> Text c </em> </p>
</html>

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

<html>
   <p> Text a <em> Text b <span class="right"> Text c </span></em></p>
   <p><em> Text a Text b <span class="right"> Text c </span></em></p>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...