C# 限制内联元素的长度
如何限制可变长度文本元素的长度,该文本元素可以包含文本属性C# 限制内联元素的长度,c#,css,string,xslt,C#,Css,String,Xslt,如何限制可变长度文本元素的长度,该文本元素可以包含文本属性(,…)和链接。在打开和关闭时都需要保留标记,但如果在适当的位置(无法删除所有标记以简化问题),则可以删除整个标记(打开和关闭)。我可以使用c#、xslt和css。我不希望用javascript来实现这一点 例如: 关于用神经网络近似实现连续映射… 请记住,标记本身(及其属性)不应计入长度 此外,文本应该换行,因此使用宽度和溢出是不可能的 首席先生和迪米特里·诺瓦切夫都有很好的解决方案。我更喜欢将这种逻辑放在xslt中,因此我选择Dimi
(,…)
和链接。在打开和关闭时都需要保留标记,但如果在适当的位置(无法删除所有标记以简化问题),则可以删除整个标记(打开和关闭)。我可以使用c#、xslt和css。我不希望用javascript来实现这一点
例如:
关于用神经网络近似实现连续映射…
请记住,标记本身(及其属性)不应计入长度
此外,文本应该换行,因此使用宽度和溢出是不可能的
首席先生和迪米特里·诺瓦切夫都有很好的解决方案。我更喜欢将这种逻辑放在xslt中,因此我选择Dimitre Novatchev作为答案,尽管两者都应该如此。这里有一个尝试性的解决方案:
public static string LimitText(string input, int width)
{
const string pattern = @"(</?[a-zA-Z0-9 '=://.]+>)";
var rgx = new Regex(pattern, RegexOptions.Compiled);
// remove tags and chop text to set width
var result = rgx.Replace(input, string.Empty).Substring(0, width);
// split till word boundary (so that "shittake" doesn't end up as "shit")
result = result.Substring(0, result.LastIndexOf(' '));
var matches = rgx.Matches(input);
// non LINQ version to keep things simple
foreach (Match match in matches)
{
var groups = match.Groups;
if (groups[0].Index > result.Length) break;
result = result.Insert(groups[0].Index, groups[0].Value);
}
// check for unbalanced tags
matches = rgx.Matches(result);
if (matches.Count % 2 != 0)
{
// chop off unbalanced tag
return result.Substring(0, matches[matches.Count-1].Groups[0].Index);
}
return result;
}
publicstaticstringlimittext(字符串输入,int-width)
{
常量字符串模式=@“(result.Length)中断;
结果=结果。插入(组[0]。索引,组[0]。值);
}
//检查不平衡的标签
matches=rgx.matches(结果);
如果(匹配。计数%2!=0)
{
//切掉不平衡的标签
返回结果。子字符串(0,匹配[matches.Count-1]。组[0]。索引);
}
返回结果;
}
注意事项:
)或打开输入
标记,则需要进行飞行前消毒。同样,获取一组匹配项,运行LimitText
,然后在结果字符串上重新插入这些标记这应该让你开始,然后你可以在任何角落的情况下扩展它。网站设计不应该限制你可以在一个容器中放置什么信息。你可以设置元素的最大高度,并使用css允许悬停时的全高-你必须使用一些定位,可能还有一些负边距来防止其他错误元素跳来跳去 或者,您可以使用文本溢出css属性,但这还没有完全实现(据我所知)-奇怪的是,它应该在ie6>中得到支持
正则表达式解决方案很困难-您需要找到去掉标记的文本结尾的位置,剪切带标记的字符串的其余部分,并附加任何未关闭的标记-这是一个棘手的问题!此XSLT 1.0转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kTextById" match="text()" use="generate-id()"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:variable name="vTextToSplit">
<xsl:apply-templates select="(//text())[1]" mode="calc"/>
</xsl:variable>
<xsl:variable name="vsplitNode" select=
"key('kTextById', substring-before(substring-after($vTextToSplit,'|'), '|'))"/>
<xsl:variable name="vsplitLength" select=
"substring-before($vTextToSplit,'|')"/>
<xsl:variable name="vsplitPos" select=
"substring-after(substring-after($vTextToSplit,'|'),'|')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not($vTextToSplit)">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()" mode="calc">
<xsl:param name="paccumLength" select="0"/>
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:variable name="vnewAccumLength" select=
"$paccumLength+string-length()"/>
<xsl:choose>
<xsl:when test="$vnewAccumLength >= $pMaxLength">
<xsl:value-of select=
"concat(string-length() - ($vnewAccumLength -$pMaxLength),
'|', generate-id(),
'|', $vPos
)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="calc"
select="(//text())[position() = $vPos+1]">
<xsl:with-param name="paccumLength" select="$vnewAccumLength"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:choose>
<xsl:when test="$vPos > $vsplitPos"/>
<xsl:when test="$vPos = $vsplitPos">
<xsl:value-of select="substring(.,1,$vsplitLength)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"text()[not(sum((.|preceding::text())/string-length(.))
gt
$pMaxLength)
]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match=
"text()[sum(preceding::text()/string-length(.))
gt
$pMaxLength
]"/>
<xsl:template match=
"text()[sum((.|preceding::text())/string-length(.))
ge
$pMaxLength
and
not(sum(preceding::text()/string-length(.))
gt
$pMaxLength)
]">
<xsl:variable name="vprevLength" select=
"sum(preceding::text()/string-length(.))"/>
<xsl:variable name="vremainingLength" select=
"$pMaxLength - $vprevLength"/>
<xsl:copy-of select="substring(.,1,$vremainingLength)"/>
</xsl:template>
</xsl:stylesheet>
<t>On the <b>approximate realization</b> of continuous mappings by <i>neu</i><a href="http://...very long link"/></t>
说明:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kTextById" match="text()" use="generate-id()"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:variable name="vTextToSplit">
<xsl:apply-templates select="(//text())[1]" mode="calc"/>
</xsl:variable>
<xsl:variable name="vsplitNode" select=
"key('kTextById', substring-before(substring-after($vTextToSplit,'|'), '|'))"/>
<xsl:variable name="vsplitLength" select=
"substring-before($vTextToSplit,'|')"/>
<xsl:variable name="vsplitPos" select=
"substring-after(substring-after($vTextToSplit,'|'),'|')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not($vTextToSplit)">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()" mode="calc">
<xsl:param name="paccumLength" select="0"/>
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:variable name="vnewAccumLength" select=
"$paccumLength+string-length()"/>
<xsl:choose>
<xsl:when test="$vnewAccumLength >= $pMaxLength">
<xsl:value-of select=
"concat(string-length() - ($vnewAccumLength -$pMaxLength),
'|', generate-id(),
'|', $vPos
)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="calc"
select="(//text())[position() = $vPos+1]">
<xsl:with-param name="paccumLength" select="$vnewAccumLength"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:choose>
<xsl:when test="$vPos > $vsplitPos"/>
<xsl:when test="$vPos = $vsplitPos">
<xsl:value-of select="substring(.,1,$vsplitLength)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"text()[not(sum((.|preceding::text())/string-length(.))
gt
$pMaxLength)
]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match=
"text()[sum(preceding::text()/string-length(.))
gt
$pMaxLength
]"/>
<xsl:template match=
"text()[sum((.|preceding::text())/string-length(.))
ge
$pMaxLength
and
not(sum(preceding::text()/string-length(.))
gt
$pMaxLength)
]">
<xsl:variable name="vprevLength" select=
"sum(preceding::text()/string-length(.))"/>
<xsl:variable name="vremainingLength" select=
"$pMaxLength - $vprevLength"/>
<xsl:copy-of select="substring(.,1,$vremainingLength)"/>
</xsl:template>
</xsl:stylesheet>
<t>On the <b>approximate realization</b> of continuous mappings by <i>neu</i><a href="http://...very long link"/></t>
$vTextToSplit
。它是一个字符串,包含三个以管道分隔的值:必须删除的“拆分节点”中的长度、生成-id()
od“拆分节点”以及“拆分节点”在所有文本节点中的顺序位置,按文档顺序排列“拆分节点”是包含要生成的文本节点总字符串的最后一个字符的文本节点generate-id()
及其要修剪的长度提取为三个共同响应的全局变量/
)的模板将检查边缘大小写。如果是,则将完整的XML文档复制到输出。如果不是这样,则通过将模板应用于其子节点来继续处理$vsplitLength
字符除外)<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kTextById" match="text()" use="generate-id()"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:variable name="vTextToSplit">
<xsl:apply-templates select="(//text())[1]" mode="calc"/>
</xsl:variable>
<xsl:variable name="vsplitNode" select=
"key('kTextById', substring-before(substring-after($vTextToSplit,'|'), '|'))"/>
<xsl:variable name="vsplitLength" select=
"substring-before($vTextToSplit,'|')"/>
<xsl:variable name="vsplitPos" select=
"substring-after(substring-after($vTextToSplit,'|'),'|')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not($vTextToSplit)">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()" mode="calc">
<xsl:param name="paccumLength" select="0"/>
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:variable name="vnewAccumLength" select=
"$paccumLength+string-length()"/>
<xsl:choose>
<xsl:when test="$vnewAccumLength >= $pMaxLength">
<xsl:value-of select=
"concat(string-length() - ($vnewAccumLength -$pMaxLength),
'|', generate-id(),
'|', $vPos
)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="calc"
select="(//text())[position() = $vPos+1]">
<xsl:with-param name="paccumLength" select="$vnewAccumLength"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:choose>
<xsl:when test="$vPos > $vsplitPos"/>
<xsl:when test="$vPos = $vsplitPos">
<xsl:value-of select="substring(.,1,$vsplitLength)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"text()[not(sum((.|preceding::text())/string-length(.))
gt
$pMaxLength)
]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match=
"text()[sum(preceding::text()/string-length(.))
gt
$pMaxLength
]"/>
<xsl:template match=
"text()[sum((.|preceding::text())/string-length(.))
ge
$pMaxLength
and
not(sum(preceding::text()/string-length(.))
gt
$pMaxLength)
]">
<xsl:variable name="vprevLength" select=
"sum(preceding::text()/string-length(.))"/>
<xsl:variable name="vremainingLength" select=
"$pMaxLength - $vprevLength"/>
<xsl:copy-of select="substring(.,1,$vremainingLength)"/>
</xsl:template>
</xsl:stylesheet>
<t>On the <b>approximate realization</b> of continuous mappings by <i>neu</i><a href="http://...very long link"/></t>
当应用于相同的源XML文档(如上所示)时,会产生相同的正确结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kTextById" match="text()" use="generate-id()"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:variable name="vTextToSplit">
<xsl:apply-templates select="(//text())[1]" mode="calc"/>
</xsl:variable>
<xsl:variable name="vsplitNode" select=
"key('kTextById', substring-before(substring-after($vTextToSplit,'|'), '|'))"/>
<xsl:variable name="vsplitLength" select=
"substring-before($vTextToSplit,'|')"/>
<xsl:variable name="vsplitPos" select=
"substring-after(substring-after($vTextToSplit,'|'),'|')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not($vTextToSplit)">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()" mode="calc">
<xsl:param name="paccumLength" select="0"/>
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:variable name="vnewAccumLength" select=
"$paccumLength+string-length()"/>
<xsl:choose>
<xsl:when test="$vnewAccumLength >= $pMaxLength">
<xsl:value-of select=
"concat(string-length() - ($vnewAccumLength -$pMaxLength),
'|', generate-id(),
'|', $vPos
)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="calc"
select="(//text())[position() = $vPos+1]">
<xsl:with-param name="paccumLength" select="$vnewAccumLength"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vPos" select="count(preceding::text())+1"/>
<xsl:choose>
<xsl:when test="$vPos > $vsplitPos"/>
<xsl:when test="$vPos = $vsplitPos">
<xsl:value-of select="substring(.,1,$vsplitLength)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name="pMaxLength" select="60"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"text()[not(sum((.|preceding::text())/string-length(.))
gt
$pMaxLength)
]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match=
"text()[sum(preceding::text()/string-length(.))
gt
$pMaxLength
]"/>
<xsl:template match=
"text()[sum((.|preceding::text())/string-length(.))
ge
$pMaxLength
and
not(sum(preceding::text()/string-length(.))
gt
$pMaxLength)
]">
<xsl:variable name="vprevLength" select=
"sum(preceding::text()/string-length(.))"/>
<xsl:variable name="vremainingLength" select=
"$pMaxLength - $vprevLength"/>
<xsl:copy-of select="substring(.,1,$vremainingLength)"/>
</xsl:template>
</xsl:stylesheet>
<t>On the <b>approximate realization</b> of continuous mappings by <i>neu</i><a href="http://...very long link"/></t>
关于连续映射的neu
函数/模板的近似实现。当我有更多的空闲时间时,我会提供第三种解决方案。这是一个很好的问题,所以你希望的是只计算这个?”在通过神经网络近似实现连续映射的过程中,某些文本“是否正确?”将其设置为内联块并设置最大宽度?@Marc B-不能正确换行,它必须像内联文本一样工作,并且可能比该行上包含其他元素的行长。纯CSS无法做到这一点,因为它没有自己的计算能力。在CSS中唯一可以做的方法是在包含元素上设置一个固定的宽度并溢出:隐藏。其他任何事情都必须通过服务器端或客户端的javascript来完成。这是一个非常好的问题,+1。有关完整的XSLT1.0解决方案,请参见我的答案。生成的结果保留了所有格式,并保留了全部可显示文本