Вот отправная точка, хотя в настоящее время она не содержит никакого кода для обработки требования "Входные теги ограничены: a, img, p, div, span, b, strong"
Itработает, проходя через дочерние узлы узла, и суммируя длину предшествующих братьев и сестер до этой точки.Обратите внимание, что код для получения длины предыдущих родственных элементов требует использования функции набора узлов, которая является функцией расширения до XSLT 1.0.В моем примере я использую функцию Microsoft Extension.
Если узел не является текстовым узлом, общая длина символов до этой точки будет суммой длин предшествующих братьев и сестер, то есть суммапредыдущие родственные элементы родительского узла (который передается в качестве параметра в шаблон).
Вот XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:param name="MAXCHARS">9</xsl:param>
<xsl:template match="/body">
<xsl:apply-templates select="child::node()"/>
</xsl:template>
<xsl:template match="node()">
<xsl:param name="LengthToParent">0</xsl:param>
<!-- Get length of previous siblings -->
<xsl:variable name="previousSizes">
<xsl:for-each select="preceding-sibling::node()">
<length>
<xsl:value-of select="string-length(.)"/>
</length>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="LengthToNode" select="sum(msxsl:node-set($previousSizes)/length)"/>
<!-- Total amount of characters processed so far -->
<xsl:variable name="LengthSoFar" select="$LengthToNode + number($LengthToParent)"/>
<!-- Check limit is not exceeded -->
<xsl:if test="$LengthSoFar < number($MAXCHARS)">
<xsl:choose>
<xsl:when test="self::text()">
<!-- Output text nonde with ... if required -->
<xsl:value-of select="substring(., 1, number($MAXCHARS) - $LengthSoFar)"/>
<xsl:if test="string-length(.) > number($MAXCHARS) - $LengthSoFar">...</xsl:if>
</xsl:when>
<xsl:otherwise>
<!-- Output copy of node and recursively call template on its children -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::node()">
<xsl:with-param name="LengthToParent" select="$LengthSoFar"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Применительно к этому входу
<body>
<img src="image.jpg" alt="" />text <a href="http://domain.tld">link here</a>
</body>
Выход:
<body>
<img src="image.jpg" alt="" />text <a href="http://domain.tld">link...</a>
</body>
При применении к этому входу (и изменение параметра на 4 в XSLT)
<p><a href="http://domain.tld">link here</a> text</p>
Выход:
<p><a href="http://domain.tld">link...</a></p>