«динамическая» нормализация - PullRequest
1 голос
/ 09 февраля 2012

Не совсем уверен, как правильно описать проблему, но я сталкиваюсь со следующим. У меня довольно много пробелов в файлах, которые изначально были HTML. Я хочу удалить это, и самый простой способ справиться с этим - использовать шаблон идентификации и добавить следующее

    <xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

Работает нормально, но слишком хорошо. Предположим следующий пример:

<p>    some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong>

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

 <p>some content with whitespaces and a<a href="some_link">link</a>and some<strong>text</strong>

но я бы хотел сохранить пробелы перед моими тегами a и strong (или, в основном, любым тегом в 'финальной' строке). Поскольку этот контент может быть в довольно некоторых тегах (div, anchors и т. Д.), Создавая исключения может сработать, но станет довольно сложным, так как мне понадобится цикл соответствия шаблонов для всех тегов, которые могут находиться внутри другого, и снова добавить пробелы после начальной очистки.

Есть ли более простой способ приблизиться к этому?

Еще раз спасибо заранее!

Ответы [ 3 ]

1 голос
/ 09 февраля 2012

Вот мое решение:

<xsl:template match="text()">
  <xsl:if test="preceding-sibling::node()[1][self::*]">
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:value-of select="normalize-space()"/>
  <xsl:if test="following-sibling::node()[1][self::*]">
    <xsl:text> </xsl:text>
  </xsl:if>
</xsl:template>

При запуске с вашим примером XML выдает:

so zacharyyoung$ xsltproc so.xsl so.xml
<?xml version="1.0"?>
<p>some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>

Обновление 1

В соответствии с вопросом Мартина, это решение вводит некоторые непреднамеренные эффекты. Учитывая этот вход:

<div>
  <h1>Heading</h1>Text
  <p>    some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>
</div>

результат:

<?xml version="1.0"?>
<div>
  <h1>Heading</h1> Text
  <p>some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>
</div>

Так что не решение общего случая.

0 голосов
/ 09 февраля 2012

Возможно

<xsl:template match="text()">
  <xsl:value-of select="concat(
    if (starts-with(., ' ') and preceding-sibling::node()[1][self::*]) then ' ' else '',
    normalize-space(.),
    if (ends-with(., ' ') and following-sibling::node()[1][self::*]) then ' ' else '')"/>
</xsl:template>
0 голосов
/ 09 февраля 2012

Может

<xsl:template match="text()[not(preceding-sibling::node()[1][self::*]) and not(following-sibling::node()[1][self::*])]">
  <xsl:value-of select="normalize-space()"/>
</xsl:template>

плюс

<xsl:template match="text()[preceding-sibling::node()[1][self::*] and not(following-sibling::node()[1][self::*])">
  <xsl:value-of select="replace(., '\s+$', '')"/>
</xsl:template>

и

<xsl:template match="text()[not(preceding-sibling::node()[1][self::*]) and following-sibling::node()[1][self::*]">
  <xsl:value-of select="replace(., '^\s+', '')"/>
</xsl:template>
...