XSLT: удаление тегов "" для for-each / select - PullRequest
0 голосов
/ 29 мая 2018

Я пытался удалить теги с   из выбора.Вот выдержка из XML

<?xml version="1.0" encoding="iso-8859-1"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html>
<body><p class="text">
  <br /><b>Header 2</b>&nbsp;
</p>
<p class="text">
  Lorem ipsum.
</p>
<p class="text">
  More lorem ipsum.
</p>
<p class="text">
  &nbsp;
</p>
<p class="text">
  &nbsp;
</p>
<p class="text">
  &nbsp;
</p>
<p class="text">
  &nbsp;
</p>
<br />
<p class="text" align="center">Header 3</p>...
</body>
</html>

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

// [local-name () = 'p' и следующий-брат :: [local-name () = 'p'] / = 'Заголовок 3' и предыдущий-брат :: [local-name () ='p'] / * = 'Заголовок 2']

Внутри этого для каждого я просто получаю значение "text ()" для каждого из узлов.Вывод xml выглядит следующим образом:

<mylabel>
  Lorem ipsum.
</mylabel><mylabel>
  More lorem ipsum.
</mylabel><mylabel>
   
</mylabel><mylabel>
   
</mylabel><mylabel>
   
</mylabel><mylabel>
   
</mylabel>

Я пытался добавить дополнительные условия для выбора, такие как not (string (text ())), string-length (text ())> 1, text()! = '' или normalize-space (.)! = '', но, похоже, &nbsp; проходит все это.

Есть ли способ удаления (не выбора) тегов с &nbsp;

1 Ответ

0 голосов
/ 29 мая 2018

Все зависит от вашей сущности. * Определено 1001 *, при условии, что оно определено как &#160;. Вы можете выбрать элементы p, не содержащие полностью пробел и этот символ неразрывного пробела с p[not(matches(., '^[\s&#160;]*$'))].

На https://xsltfiddle.liberty -development.net / 94hvTz6 вы можете видеть, что предлагаемый предикат исключает элементы p только с пробелом и эту неразрывную пробелную ссылку на объект,Например, просто делает

  <xsl:template match="/">
      <xsl:copy-of select="//p[not(matches(., '^[\s&#160;]*$'))]"/>
  </xsl:template>

на ваших данных выборки, и в результате получается

<p class="text">
  <br/><b>Header 2</b> 
</p><p class="text">
  Lorem ipsum.
</p><p class="text">
  More lorem ipsum.
</p><p class="text" align="center">Header 3</p>

Если вы проверите https://xsltfiddle.liberty -development.net / 94hvTz6 / 2 , тоВы можете видеть, что выбор или исключение XPath работает с вашим отредактированным образцом и объявленной сущностью, очевидно, если вы включите полный DTD XHTML, который помещает элементы в пространство имен XHTML, тогда необходимо отрегулировать XSLT, чтобы учитывать пространство имен с помощью

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="http://www.w3.org/1999/xhtml"
    version="3.0">

    <xsl:template match="/">
        <xsl:copy-of select="//p[not(matches(., '^[\s&#160;]*$'))]"/>
    </xsl:template>

</xsl:stylesheet>

или, как сказано в комментарии, использование *:p.

xsltfiddle не будет работать с XML и DTD, поэтому вы не можете проверить его там, новнутри oXygen или с Saxon из командной строки предложение должно сработать.

...