Извлечение непрерывных братьев и сестер в XSL - PullRequest
2 голосов
/ 17 декабря 2011

У меня есть HTML-файл, подобный следующему:

<root>
    <br>
    <h3>The first H3 text</h3><br>
    <p>para1 content in first H3</p><br>
    <p>para2 content in first H3</p><br>
    <h3>The second H3 text</h3><br>
    <p>para1 content in second H3</p><br>
    <p>para2 content in second H3</p><br>
    <p>para3 content in second H3</p><br>
    <p>para4 content in second H3</p><br>
</root>

Я хочу написать XSL, который выдает такой результат:

<sec>
    <br />
    <secHead>The first H3 text</secHead><br />
    <para>para1 content in first H3</para><br />
    <para>para2 content in first H3</para><br />
</sec>
<br />
<sec>
    <br/>
    <secHead>The second H3 text</secHead><br/>
    <para>para1 content in second H3</para><br/>
    <para>para2 content in second H3</para><br/>
    <para>para3 content in second H3</para><br/>
    <para>para4 content in second H3</para><br/>
</sec>

Как мы можем получитьвывод записи XSL?

1 Ответ

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

Хороший вопрос, + 1.

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

<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:key name="kFollowing" match="*[not(self::h3)]"
  use="generate-id(preceding-sibling::h3[1])"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="h3"/>
 </xsl:template>

 <xsl:template match="h3">
    <xsl:if test="position() > 1">
     <br />
    </xsl:if>
     <sec>
      <br />
      <secHead><xsl:value-of select="."/></secHead>
      <xsl:copy-of select="key('kFollowing', generate-id())"/>
     </sec>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному источнику (HTML должен быть преобразован в хорошо сформированный XML !!!):

<root>
    <br/>
    <h3>The first H3 text</h3><br/>
    <p>para1 content in first H3</p><br/>
    <p>para2 content in first H3</p><br/>
    <h3>The second H3 text</h3><br/>
    <p>para1 content in second H3</p><br/>
    <p>para2 content in second H3</p><br/>
    <p>para3 content in second H3</p><br/>
    <p>para4 content in second H3</p><br/>
</root>

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

<sec>
   <br/>
   <secHead>The first H3 text</secHead>
   <br/>
   <p>para1 content in first H3</p>
   <br/>
   <p>para2 content in first H3</p>
   <br/>
</sec>
<br/>
<sec>
   <br/>
   <secHead>The second H3 text</secHead>
   <br/>
   <p>para1 content in second H3</p>
   <br/>
   <p>para2 content in second H3</p>
   <br/>
   <p>para3 content in second H3</p>
   <br/>
   <p>para4 content in second H3</p>
   <br/>
</sec>

Объяснение

Ключевым моментом в этом решении является то, что мы определяем xsl:key, который фиксирует связь между элементом h3 и всеми его ближайшими соседними элементами (так что они сами не являются h3 и этим h3 их первый h3 предшествующий родной брат).

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