Функция normalize-space
удаляет начальные и конечные пробелы и заменяет последовательности пробельных символов одним пробелом. Как я могу только заменять последовательности пробелов одним пробелом в XSLT 1.0? Например, "..x.y...\n\t..z."
(пробелы заменены точкой для удобства чтения) должно стать ".x.y.z."
.
Как заменить последовательность пробелов одним пробелом, но не обрезать в XSLT?
comment
Хороший вопрос, +1. См. мой ответ для однострочного выражения XPath 1.0 - решение (и, конечно же, это также решение XSLT 1.0). :) Функции расширения не требуются/не используются.
- person Dimitre Novatchev   schedule 18.02.2011
comment
Проверьте мой ответ для решения с тремя вызовами функций.
- person   schedule 18.02.2011
Ответы (2)
Без метода Беккера вы могли бы использовать некоторый нежелательный символ в качестве отметки :
translate(normalize-space(concat('',.,'')),'','')
Примечание. Три вызова функций...
Или с любым символом, но повторяющим какое-то выражение:
substring(
normalize-space(concat('.',.,'.')),
2,
string-length(normalize-space(concat('.',.,'.'))) - 2
)
В XSLT вы можете легко объявить переменную:
<xsl:variable name="vNormalize" select="normalize-space(concat('.',.,'.'))"/>
<xsl:value-of select="susbtring($vNormalize,2,string-length($vNormalize)-2)"/>
person
Community
schedule
18.02.2011
Спасибо, использование обескураженных символов — хитрый трюк. Вы только забыли
;
после каждого объекта персонажа (или он потерялся при редактировании).
- person Jakob; 20.02.2011
@Jakob: Добро пожаловать. Также вы правы: я забыл последний
;
в сущностях. Извиняюсь.
- person ; 21.02.2011
Используйте это выражение XPath 1.0:
concat(substring(' ', 1 + not(substring(.,1,1)=' ')),
normalize-space(),
substring(' ', 1 + not(substring(., string-length(.)) = ' '))
)
Чтобы убедиться в этом, выполните следующее преобразование:
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select=
"concat(substring(' ', 1 + not(substring(.,1,1)=' ')),
normalize-space(),
substring(' ', 1 + not(substring(., string-length(.)) = ' '))
)
"/>
</xsl:template>
</xsl:stylesheet>
при применении к этому XML-документу:
<t>
<t1> xxx yyy zzz </t1>
<t2>xxx yyy zzz</t2>
<t3> xxx yyy zzz</t3>
<t4>xxx yyy zzz </t4>
</t>
выдает желаемый правильный результат:
<t>
<t1> xxx yyy zzz </t1>
<t2>xxx yyy zzz</t2>
<t3> xxx yyy zzz</t3>
<t4>xxx yyy zzz </t4>
</t>
person
Dimitre Novatchev
schedule
18.02.2011
Спасибо! Я буду использовать метод Алехандро, хотя он основан на данных, не содержащих специального символа. Оба ответа полезны :-)
- person Jakob; 20.02.2011
@Jacob: Добро пожаловать. Я предполагаю, что вы выбрали ответ @Alejandro, потому что он разделил выражение на переменные и, таким образом, сделал его более понятным. Возможно, вы знаете, что между собой мы гордимся тем, что предоставляем однострочные решения XPath :)
- person Dimitre Novatchev; 20.02.2011
Я должен признать, что в сомнениях я выбираю ответ от пользователя с меньшей репутацией (если есть несколько одинаковых ответов), просто чтобы сократить разрыв ;-) XPath великолепен. Если бы только XSLT имел более читаемый синтаксис, подобный XPath!!
- person Jakob; 21.02.2011
@Jacob: В XSLT 2.0 можно почти полностью кодировать только в XPath 2.0. Еще лучше в XSLT 3.0.
- person Dimitre Novatchev; 21.02.2011