Как обрезать текст так, чтоб применился шаблон?

Александр83

Новичок
Как обрезать текст так, чтоб применился шаблон?

Люди добрые подскажите пожалуйста! Как мне обрезать текст так, чтоб применился шаблон highlight?

XML примерно в таком виде:
<text> Music from Grey Anatomy - Chasing <highlight>Cars</highlight> by Snow Patrol (Universal Records) </text>

Highlight описан вот так-
<xsl:template match="highlight">
<nobr>
<b>
<xsl:value-of select="."/>
</b>
</nobr>
</xsl:template>

Пробую -
<xsl:value-of select="substring(text, 0, 50)"/>
<xsl:text>...</xsl:text>

Тогда на выходе получаеться
Music from Grey Anatomy - Chasing Cars by Snow Pat...

На надо чтоб получилось вот так -
Music from Grey Anatomy - Chasing <b>Cars</b> by S...

Подскажите, пожалуйста, как надо написать, чтоб правильно отработал шаблон Highlight?
 

slach

Новичок
substring(text, 0, 50)
никогда тебе не даст ВМЕСТЕ с ТЕГАМИ ничего потому что теги это nodeset
а на вход substing твой nodeset преобразуется к скалярному типу строка и соответсвенно теги теряются

судя по всему в ЛОБ твоя задача н решается ни с помощью XSLT (поскольку нельзя отловить ТЕГИ) ни с помощью EXSLT

попробуй обратись в fido7.ru.xml возможно там помогут
http://groups.google.com/group/fido7.ru.xml/
 

jian

Новичок
PHP:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="data.xsl"?>
<text> Music from Grey Anatomy - Chasing <highlight>Cars</highlight> by Snow Patrol (Universal Records) </text>


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="highlight">
<nobr>
<b>
<xsl:value-of select="."/>
</b>
</nobr>
</xsl:template>


</xsl:stylesheet>
 

slach

Новичок
jian
а теперь сделай так
чтобы вместо ВСЕГО <text> обрабатывалось только первые 50 символов....??? а???
причем без учета тегов

-~{}~ 25.06.07 08:53:

автору топика, IMHO если у тебя есть возможность проще формировать строку заранее или воспользоваться php-Callback

что нибудь типа


PHP:
<?xml version="1.0" encoding="ISO-8859-1"?> 
<text> Music from Grey Anatomy - Chasing <highlight>Cars</highlight> by Snow Patrol (Universal Records) </text> 


<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
<xsl:variable name="transformed_text">
    <xsl:apply-templates select="." mode="highlight"/> 
</xsl:variable>
<xsl:value-of select="php:function('myStrReplaceInDOMNode',$variable,0,50)" />
</xsl:template> 

<xsl:template match="//highlight" mode="highlight"> 
<nobr> 
<b> 
<xsl:value-of select="."/> 
</b> 
</nobr> 
</xsl:template> 


</xsl:stylesheet>


как написать
myStrReplaceInDOMNode
я надеюсь сам догадаешься
 

Alexandre

PHPПенсионер
судя по всему в ЛОБ твоя задача н решается ни с помощью XSLT (поскольку нельзя отловить ТЕГИ) ни с помощью EXSLT
решается...
надо написать еще один шаблон, который вычисляет первый пробел после 40 -го символа,
далее применяем шаблон, в который передаем полученное значение и в этом шаблоне делаем substr(),

вариант 2) можно используя RegExp (для EXSLT, в libxslt он встраивается как плагин) выделить и заменить то что нужно (если хорошо знаешь реги)

принципиально задача решаема (нечто похожее было в тестах для Яндекса)

в общем геморой, по этому вариант с php-Callback наиболее оптимальный.
 

jian

Новичок
gromozdko, no jit mojno.
mojet obrabativat neskolko highlightov, pravda po _kajdoi_bukve_


PHP:
xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="data.xsl"?>
<text>Music <highlight>from</highlight> Grey <highlight>Anatomy</highlight> - Chasing <highlight>Cars</highlight> by Snow Patrol (Universal Records)   </text>

xsl:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<!--xsl:param name="debug" select="'false'"/-->
<xsl:param name="debug" select="'true'"/>
<xsl:param name="ggll" select="36"/>

<xsl:template match="/">
	<table border="1">
		<xsl:apply-templates select="text/highlight[1]" mode="my"/>
	</table>
</xsl:template>


<xsl:template match="highlight" mode="my">
	<xsl:param name="my">
		<xsl:apply-templates select="preceding-sibling::text()|preceding-sibling::highlight"/>
	</xsl:param>
	<xsl:param name="sta"/>
	<xsl:param name="end"/>
	<xsl:param name="curSta">
		<xsl:choose>
			<xsl:when test="$sta">
				<xsl:value-of select="concat($sta, string-length($my))"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="string-length($my)"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:param>
	<xsl:param name="curEnd">
		<xsl:choose>
			<xsl:when test="$end">
				<xsl:value-of select="concat($end, string-length($my) + string-length(.))"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="string-length($my) + string-length(.)"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:param>
	<xsl:param name="myLast" select="following-sibling::text()[1]"/>

	<xsl:choose>
		<xsl:when test="following-sibling::highlight[1]">
			<xsl:apply-templates select="following-sibling::highlight[1]" mode="my">
				<xsl:with-param name="sta" select="concat($curSta, ',')"/>
				<xsl:with-param name="end" select="concat($curEnd, ',')"/>
			</xsl:apply-templates>
		</xsl:when>
		<xsl:otherwise>
			<xsl:call-template name="seeOut">
				<xsl:with-param name="sta" select="concat($curSta, ',')"/>
				<xsl:with-param name="end" select="concat($curEnd, ',')"/>
				<xsl:with-param name="my" select="concat($my, ., $myLast)"/>
			</xsl:call-template>
		</xsl:otherwise>
	</xsl:choose>

</xsl:template>

<xsl:template name="seeOut">
	<xsl:param name="sta"/>
	<xsl:param name="end"/>
	<xsl:param name="my"/>
	<xsl:param name="count" select="1"/>
	<xsl:param name="acum"/>

	<xsl:if test="$debug = 'true'">
		<xsl:call-template name="doText">
			<xsl:with-param name="my" select="$my"/>
			<xsl:with-param name="acum" select="$acum"/>
		</xsl:call-template>
	</xsl:if>

	<xsl:choose>
		<xsl:when test="$ggll >= $count">
			<xsl:call-template name="seeOut">
				<xsl:with-param name="sta">
					<xsl:choose>
						<xsl:when test="$count > substring-before($end, ',')">
							<xsl:value-of select="substring-after($sta, ',')"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$sta"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:with-param>
				<xsl:with-param name="end">
					<xsl:choose>
						<xsl:when test="$count > substring-before($end, ',')">
							<xsl:value-of select="substring-after($end, ',')"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="$end"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:with-param>
	
				<xsl:with-param name="my" select="$my"/>
				<xsl:with-param name="count" select="$count + 1"/>
				<xsl:with-param name="acum">
					<xsl:copy-of select="$acum"/>
					<xsl:choose>
						<xsl:when test="$count > substring-before($sta, ',') and substring-before($end, ',') >= $count">
							<b><xsl:value-of select="substring($my, $count, 1)"/></b>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="substring($my, $count, 1)"/>
						</xsl:otherwise>
				</xsl:choose>
				</xsl:with-param>
			</xsl:call-template>
		</xsl:when>
		<xsl:otherwise>
			<xsl:if test="$debug = 'false'">
				<xsl:call-template name="doText">
					<xsl:with-param name="my" select="$my"/>
					<xsl:with-param name="acum" select="$acum"/>
				</xsl:call-template>
			</xsl:if>
		</xsl:otherwise>
	</xsl:choose>

</xsl:template>


<xsl:template name="doText">
	<xsl:param name="my"/>
	<xsl:param name="acum"/>
	<tr>
		<td>
			<xsl:copy-of select="$acum"/>
			<xsl:if test="string-length(normalize-space($my)) > $ggll">...</xsl:if>
		</td>
	</tr>
</xsl:template>

</xsl:stylesheet>
-~{}~ 25.06.07 13:17:

eto pryamo s konveiera, poetomu gromozdko.
dumayu, chut-chut optimizacii ne pomeshaet.
kak nibud optimiziruyu.
 

atv

Новичок
На надо чтоб получилось вот так -
Music from Grey Anatomy - Chasing <b>Cars</b> by S...
а теперь сделай так
чтобы вместо ВСЕГО <text> обрабатывалось только первые 50 символов....??? а???
причем без учета тегов
Разве автор топика этого хотел?

Помоему jian дал правильный ответ.
 

jian

Новичок
optimiziciya nomer 1:
1) kogda net hailaitov.
2) kogda 2 hailaita idut drug za drugom
3) pri "debug=true", isklyuchaet 1vuyu holostuyu.

PHP:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<!--xsl:param name="debug" select="'false'"/-->
<xsl:param name="debug" select="'true'"/>
<xsl:param name="ggll" select="45"/>

<xsl:template match="/">
    <table border="1">
		<xsl:choose>
			<xsl:when test="text/highlight[1]">
		        <xsl:apply-templates select="text/highlight[1]" mode="my"/>
			</xsl:when>
			<xsl:otherwise>
			    <tr>
			        <td>
						<xsl:value-of select="substring(text, 0, $ggll)"/>
						<xsl:text>...</xsl:text>
			        </td>
			    </tr>
			</xsl:otherwise>
		</xsl:choose>
    </table>
</xsl:template>

<xsl:template match="highlight" mode="my">
    <xsl:param name="my">
        <xsl:apply-templates select="preceding-sibling::text()|preceding-sibling::highlight"/>
    </xsl:param>
    <xsl:param name="sta"/>
    <xsl:param name="end"/>
    <xsl:param name="curSta">
        <xsl:choose>
            <xsl:when test="$sta">
                <xsl:value-of select="concat($sta, string-length($my))"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="string-length($my)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="curEnd">
        <xsl:choose>
            <xsl:when test="$end">
                <xsl:value-of select="concat($end, string-length($my) + string-length(.))"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="string-length($my) + string-length(.)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="myLast" select="following-sibling::text()[1]"/>
    <xsl:choose>
        <xsl:when test="following-sibling::highlight[1]">
            <xsl:apply-templates select="following-sibling::highlight[1]" mode="my">
                <xsl:with-param name="sta" select="concat($curSta, ',')"/>
                <xsl:with-param name="end" select="concat($curEnd, ',')"/>
            </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="seeOut">
                <xsl:with-param name="sta" select="concat($curSta, ',')"/>
                <xsl:with-param name="end" select="concat($curEnd, ',')"/>
                <xsl:with-param name="my" select="concat($my, ., $myLast)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="seeOut">
    <xsl:param name="sta"/>
    <xsl:param name="end"/>
    <xsl:param name="my"/>
    <xsl:param name="count" select="1"/>
    <xsl:param name="acum"/>

    <xsl:if test="$debug = 'true' and $count > 1">
        <xsl:call-template name="doText">
            <xsl:with-param name="my" select="$my"/>
            <xsl:with-param name="acum" select="$acum"/>
        </xsl:call-template>
    </xsl:if>

    <xsl:choose>
        <xsl:when test="$ggll >= $count">
            <xsl:call-template name="seeOut">
                <xsl:with-param name="sta">
                    <xsl:choose>
                        <xsl:when test="$count >= substring-before($end, ',')">
                            <xsl:value-of select="substring-after($sta, ',')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$sta"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:with-param>
                <xsl:with-param name="end">
                    <xsl:choose>
                        <xsl:when test="$count >= substring-before($end, ',')">
                            <xsl:value-of select="substring-after($end, ',')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$end"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:with-param>
                <xsl:with-param name="my" select="$my"/>
                <xsl:with-param name="count" select="$count + 1"/>
                <xsl:with-param name="acum">
                    <xsl:copy-of select="$acum"/>
                    <xsl:choose>
                        <xsl:when test="$count > substring-before($sta, ',') and substring-before($end, ',') >= $count">
                            <b><xsl:value-of select="substring($my, $count, 1)"/></b>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="substring($my, $count, 1)"/>
                        </xsl:otherwise>
                </xsl:choose>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:if test="$debug = 'false'">
                <xsl:call-template name="doText">
                    <xsl:with-param name="my" select="$my"/>
                    <xsl:with-param name="acum" select="$acum"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:otherwise>
    </xsl:choose>

</xsl:template>

<xsl:template name="doText">
    <xsl:param name="my"/>
    <xsl:param name="acum"/>
    <tr>
        <td>
            <xsl:copy-of select="$acum"/>
            <xsl:if test="string-length(normalize-space($my)) > $ggll">...</xsl:if>
        </td>
    </tr>
</xsl:template>

</xsl:stylesheet>
 
Сверху