我使用XSLT从XML中提取数据。我想在xml-editor中查看数据。如何将文本换行以适应XSLT中的窗口?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match='/'>
<wawes>
<xsl:for-each select="//VARIABLE">
<xsl:sort select="@ID" order="descending"/>
<wave>
<id>
<xsl:value-of select="@ID" ></xsl:value-of>
</id>
<NAME>
<xsl:value-of select="NAME"/>
</NAME>
</wave>
</xsl:for-each>
</wawes>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
为了适应屏幕大小或分辨率而环绕文本通常与XSLT无关。 XSLT只关注转换XML,而不关心XML数据的表示和布局。
如果您认为这不是太糟糕:所有类型的屏幕尺寸,分辨率以及所有类型的应用程序(包括XML编辑器)都必须同样可以访问相同的XML。将XML与这三个因素的独特组合(窗口大小怎么样?)放在一起是很冒昧的。
相反,正如@rene指出的那样,包装文本几乎是每个文本编辑器的一个功能。例如,在UltraEdit中有 CTRL + W 。
N.b。在技术上不可能在XSLT中强制包装文本。您可以在元素的文本内容中引入换行符。但
答案 1 :(得分:0)
我的其他答案使用XSLT-2
提供了解决方案,而此问题的初始范围为XSLT-1
。
这个前提是基于这样的想法:反复重复目标字符串,切掉可变大小的子50段并将每个段放在它自己的行上,然后继续这个功能,直到没有更多的文本可用。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:user="http://www.altova.com/MapForce/UDF/user" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="user xs">
<xsl:template name="user:FindLastSpace">
<xsl:param name="text" select="/.."/>
<xsl:variable name="var1_resultof_string_length" select="string-length($text)"/>
<xsl:variable name="var4_result">
<xsl:choose>
<xsl:when test="string(('0' = $var1_resultof_string_length)) != 'false'">
<xsl:value-of select="'0'"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="var2_resultof_substring" select="substring($text, $var1_resultof_string_length)"/>
<xsl:variable name="var3_result">
<xsl:value-of select="($var2_resultof_substring = ' ')"/>
<xsl:value-of select="($var2_resultof_substring = ',')"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="string(boolean(translate(normalize-space($var3_result), 'false0 ', ''))) != 'false'">
<xsl:value-of select="$var1_resultof_string_length"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="substring($text, '1', ($var1_resultof_string_length - '1'))"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="floor($var4_result)"/>
</xsl:template>
<xsl:template name="user:CrLf">
<xsl:value-of select="'
'"/>
</xsl:template>
<xsl:template name="user:FormLines">
<xsl:param name="remainingText" select="/.."/>
<xsl:param name="length" select="/.."/>
<xsl:variable name="var1_resultof_substring" select="substring($remainingText, '1', $length)"/>
<xsl:variable name="var2_resultof_FindLastSpace">
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="var4_result">
<xsl:choose>
<xsl:when test="string(($var2_resultof_FindLastSpace = '0')) != 'false'">
<xsl:variable name="var3_resultof_string_length" select="string-length($remainingText)"/>
<xsl:value-of select="$var3_resultof_string_length"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="var5_resultof_CrLf">
<xsl:call-template name="user:CrLf"/>
</xsl:variable>
<xsl:variable name="var6_resultof_FindLastSpace">
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="var8_result">
<xsl:choose>
<xsl:when test="string(($var6_resultof_FindLastSpace = '0')) != 'false'">
<xsl:variable name="var7_resultof_string_length" select="string-length($remainingText)"/>
<xsl:value-of select="$var7_resultof_string_length"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="var11_result">
<xsl:choose>
<xsl:when test="string((substring($remainingText, ($var8_result + '1')) = '')) != 'false'">
<xsl:value-of select="''"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="var9_resultof_FindLastSpace">
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="var10_result">
<xsl:choose>
<xsl:when test="string(($var9_resultof_FindLastSpace = '0')) != 'false'">
<xsl:value-of select="string-length($remainingText)"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="user:FindLastSpace">
<xsl:with-param name="text" select="$var1_resultof_substring"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="user:FormLines">
<xsl:with-param name="remainingText" select="substring($remainingText, ($var10_result + '1'))"/>
<xsl:with-param name="length" select="$length"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat(concat(substring($remainingText, '1', $var4_result), $var5_resultof_CrLf), $var11_result)"/>
</xsl:template>
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xformResult>
<xsl:call-template name="user:FormLines">
<xsl:with-param name="remainingText" select="'Google HQ, 345 Spear St, San Francisco, Foo, Bar, Baz, 012310123'"/>
<xsl:with-param name="length" select="floor('50')"/>
</xsl:call-template>
</xformResult>
</xsl:template>
</xsl:stylesheet>
在许多测试中都能很好地工作。请原谅我的疯狂,我把它扔在MapForce中
答案 2 :(得分:-1)
使用正则表达式使用XSLT-2
的{{1}}函数(替换为replace
)来分解字符串,我取得了相当的成功。我知道你关注$1\n
,但是从我发现的情况来看,正则表达式是没有迭代解析的唯一方法。
最初,我发现this question and answer,但是我无法让它在XSLT允许的正则表达式子集中工作,主要是由于缺乏积极的前瞻而受阻。
虽然XSLT是关于XML操作的,但我的工作已经证明,这不是唯一的用例,因为我们使用XSLT来执行大规模数据转换以实现系统和客户端的互操作性,不仅仅是XML数据,还有纯文本和格式化文本(即CSV)数据。
一个这样的转变需要一组地址元素的内爆:
XSLT-1
进入一个类似于:
的文本块<Address>
<Name>Google HQ</Name>
<Line1>345 Spear St</Line1>
<Line2></Line2>
<Line3></Line3>
<Line4></Line4>
<City>San Francisco</City>
<PostCode>94105</PostCode>
<County>CA</County>
<Country>United States</Country>
<CountryCode>USA</CountryCode>
</Address>
但是,此信息将被放入的字段仅限于4行,每行为50个字符。为了节省空间,我将Google HQ,
345 Spear St,
San Francisco,
94105,
CA,
USA
,PostCode
和County
放在一行并单独添加,因此我有3行50个字符。然后我拿走剩余的字段,并将它们一起CSV(除非一个是空白的),这样看起来像:
Google HQ,345 Spear St,San Francisco
看看我上面提到的问题和答案,我得到了正则表达式(交换长度为16的50):
CountryCode
但是,它在XSLT中不起作用。
对于初学者来说,它不会识别(?:((?>.{1,50}(?:(?<=[^\S\r\n])[^\S\r\n]?|(?=\r?\n)|$|[^\S\r\n]))|.{1,50})(?:\r?\n)?|(?:\r?\n|$))
(原子组)或(?>
(正向前瞻,但在与匿名组交换后,它可以正常工作。
但在那之后,我得到了与零长度字符串匹配的错误。这是由(?=
的最后一次出现引起的,这导致它与行尾匹配,但没有它,它最终起作用。它并不像我希望的那样整洁,但它确实将单行文本压缩成一组每行都小于50个字符的行。最后的正则表达式是:
|$
现在,在我不适合你的情况下,我也有线路限制,但我只是丢弃了其余的线路。
希望对你有所帮助