XSL-тест, если встречается самозакрывающийся элемент в цикле for-each - PullRequest
0 голосов
/ 14 декабря 2011

Вот пример XML:

<a>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
    <page/>
    <b>Text</b>
    <b>Text</b>
    <page/>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
    <b>Text</b>
</a>

А вот HTML, который я хочу достичь:

<p>Text Text Text</p>
<p>Text Text</p>
<p>Text Text Text Text</p>

Я впервые использую XSL, поэтому, пожалуйста, прости меня.

Сейчас я использую этот цикл:

<xsl:for-each select="a/*">
    <p>
    <xsl:value-of select="."/>
    <xsl:if test="UNKNOWN_TEST">
    </p>
    </xsl:if>
</xsl:for-each>

Мой вопрос: что мне нужно здесь печатать вместо UNKNOWN_TEST?Или, может быть, это не так, как я должен пытаться решить это?

Ответы [ 2 ]

1 голос
/ 14 декабря 2011

Ошибочно думать о XSLT как об обработке буквального текста документа.Он работает над моделью, представлением, в котором <page/> и <page></page> эквивалентны.Однако вы сделали следующий комментарий к предыдущему ответу:

Каждая b - это строка текста из книги.Каждый <page/> означает, что одна страница закончилась, а следующая начинается.Поэтому я хочу, чтобы каждая "страница" (b с между <page/> с) была обернута внутри <p>.Я надеюсь, что это немного объясняет.

Следующая таблица стилей использует key для группировки b элементов по предшествующим page:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:key name="byPage" match="b" 
             use="generate-id(preceding-sibling::page[1])"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="a">
        <xsl:copy>
            <!-- handle the first group of b's with no preceding page -->
            <p><xsl:apply-templates select="key('byPage', '')"/></p>
            <xsl:apply-templates select="@*|page"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="page">
        <p><xsl:apply-templates select="key('byPage', generate-id())"/></p>
    </xsl:template>
</xsl:stylesheet>

На выходе получается:

<a>
   <p>
      <b>Text</b>
      <b>Text</b>
      <b>Text</b>
   </p>
   <p>
      <b>Text</b>
      <b>Text</b>
   </p>
   <p>
      <b>Text</b>
      <b>Text</b>
      <b>Text</b>
      <b>Text</b>
   </p>
</a>
1 голос
/ 14 декабря 2011

Вы не можете видеть, является ли он самозакрытым, вы можете проверить, если он пустой, он все равно не будет работать, потому что ваш xsl не правильно сформирован.

Возможно (не очень приятно) решение:

<?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:for-each select="/a/b[name(preceding-sibling::*[1])!='b']">
   <p>
    <xsl:value-of select="text()"/>
    <xsl:variable name="pp" select="generate-id(preceding-sibling::page[1])" />
    <xsl:variable name="fp" select="generate-id(following-sibling::page[1])" />
    <xsl:for-each select="following-sibling::b[generate-id(preceding-sibling::page[1])=$pp and generate-id(following-sibling::page[1])=$fp]">
     <xsl:value-of select="concat(' ',./text())"/>
    </xsl:for-each>
   </p>
  </xsl:for-each>
 </xsl:template>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...