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

Все учебники и примеры, которые я нашел по обработке XSLT, похоже, предполагают, что ваш пункт назначения будет существенно отличаться по формату / структуре от вашего источника, и что вы заранее знаете структуру источника. Я пытаюсь выяснить, как выполнять простые «на месте» модификации HTML-документа, не зная ничего о его существующей структуре.

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

1.) delete the classname 'foo' from all divs
2.) delete a node if its empty (ie <p></p>)
3.) delete a <p> node if its first child is <br>
4.) add newattr="newvalue" to all H1
5.) replace 'heading' in text nodes with 'title'
6.) wrap all <u> tags in <b> tags (ie, <u>foo</u> -> <b><u>foo</u></b>)
7.) output the transformed document without changing anything else

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

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

<!doctype html>
<html>
<body>
  <h1>heading</h1>
  <p></p>
  <p><br>line</p>
  <div class="foo bar"><u>baz</u></div>
  <p>untouched</p>
</body>
</html>

выход:

<!doctype html>
<html>
<body>
  <h1 newattr="newvalue">title</h1>
  <div class="bar"><b><u>baz</u></b></div>
  <p>untouched</p>
</body>
</html>

1 Ответ

3 голосов
/ 09 марта 2010

1.) Удалить имя класса 'foo' из всех элементов div

<xsl:template match="div[contains(concat(' ', @class, ' '), ' foo ')]">
  <xsl:copy>
    <xsl:attribute name="class">
      <xsl:variable name="s" select="substring-before(concat(' ', @class, ' '), ' foo ')" />
      <xsl:variable name="e" select="substring-after(concat(' ', @class, ' '), ' foo ')" />
      <xsl:value-of select="normalize-space(concat($s, ' ', $e))" />
    </xsl:attribute>
    <xsl:apply-templates select="node() | @*[not(self::@class)]" />
  </xsl:copy>
</xsl:template>

2.) Удалить узел, если он пустой (т. Е. <p></p>)

<xsl:template match="*[normalize-space() = '']" />

3.) Удалить узел

, если его первый дочерний элемент равен <br>

<xsl:template match="p[*[1]/self::br]" />

4.) Добавить newattr="newvalue" ко всем <h1>

<xsl:template match="h1[not(@newattr)]">
  <xsl:copy>
    <xsl:attribute name="newattr">
      <xsl:value-of select="'newvalue'" />
    </xsl:attribute>
    <xsl:apply-templates select="node() | @*" />
  </xsl:copy>
</xsl:template>

5.) Заменить заголовок в текстовых узлах на заголовок

<!-- This replaces the first occurrence of 'heading', case-sensitively.
     More generic search-and-replace templates are plenty, here on SO as well as 
     elsewhere on the 'net. -->
<xsl:template match="text()[contains(concat(' ', ., ' '), ' heading ')]">
  <xsl:variable name="s" select="substring-before(concat(' ', ., ' '), ' heading ')" />
  <xsl:variable name="e" select="substring-after(concat(' ', ., ' '), ' title ')" />
  <xsl:value-of select="normalize-space(concat($s, ' ', $e))" />
</xsl:template>

6.) Обернуть все теги <u> в теги <b> (т. Е. <u>foo</u> -> <b><u>foo</u></b>)

<xsl:template match="u[not(parent::*/self::b)]">
  <b>
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </b>
</xsl:template>

7.) Вывести преобразованный документ без каких-либо изменений

<!-- the identity template copies everything that is not handled by 
     any of the more specific templates above -->
<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*" />
  </xsl:copy>
</xsl:template>

Порядок и специфичность шаблона определяют, какой шаблон «выигрывает», когда несколько шаблонов могут соответствовать одному узлу.

Более конкретно означает: «Из нескольких конкурирующих шаблонов выигрывает тот, который имеет более сложное правило соответствия».

Порядок означает: «Из нескольких конкурирующих шаблонов с одинаковой специфичностью побеждает тот, что позже в документе XSLT.

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