我试图找到一个更好的解决方案来将纯文本(但每个字段具有预定义的长度)转换为 xml。
例如输入文本可以是
“Testuser new york 10018”,前11个字符表示用户名,后12个字符表示城市,后5个字符表示邮政编码。
所以我需要从上面的字符串中形成一个具有预定义字段长度的 xml。
我在想 2 种方法
在输入文本上使用子字符串函数。
最佳答案
以下语句: (XSLT) "isn't suitable for transforming from structured text to XML. "
和语句 "XSLT
must
have XML as the input document"
** 都是错误的 。
实际上,使用 XSLT 很容易实现方法 2:
一、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:template match="/*/text()" name="processLines">
<xsl:param name="pText" select="."/>
<xsl:if test="contains($pText, '
')">
<xsl:variable name="vLine" select=
"substring-before($pText, '
')"/>
<user>
<name>
<xsl:value-of select=
"translate(substring-before($vLine, ' '),'_',' ')"/>
</name>
<city>
<xsl:value-of select=
"translate(substring-before(substring-after($vLine, ' '),' '),
'_',
' '
)
"/>
</city>
<zipCode>
<xsl:value-of select=
"translate(substring-after(substring-after($vLine, ' '),' '),
'_',
' '
)
"/>
</zipCode>
</user>
<xsl:call-template name="processLines">
<xsl:with-param name="pText" select=
"substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当此转换应用于特殊格式的文本 时(包装在单个顶部元素中以使其格式良好——正如我们将在 XSLT 2.0 中看到的那样,不需要这样的包装):
<t>Testuser new_york 10018
usera seattle 98000
userb bellevue 98004
userb redmond 98052
</t>
产生了想要的结果 :
<user>
<name>Testuser</name>
<city>new york</city>
<zipCode>10018</zipCode>
</user>
<user>
<name>usera</name>
<city>seattle</city>
<zipCode>98000</zipCode>
</user>
<user>
<name>userb</name>
<city>bellevue</city>
<zipCode>98004</zipCode>
</user>
<user>
<name>userb</name>
<city>redmond</city>
<zipCode>98052</zipCode>
</user>
注释 :
II. XSLT 2.0 解决方案 :
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vText" select=
"unparsed-text('file:///c:/temp/delete/delete.txt')"/>
<xsl:variable name="vLines" select=
"tokenize($vText, '
?
')[normalize-space()]"/>
<xsl:template match="/">
<xsl:for-each select="$vLines">
<xsl:variable name="vFields" select=
"tokenize(., ' ')[normalize-space()]"/>
<user>
<name>
<xsl:sequence select="translate($vFields[1], '_',' ')"/>
</name>
<city>
<xsl:sequence select="translate($vFields[2], '_',' ')"/>
</city>
<zipCode>
<xsl:sequence select="translate($vFields[3], '_',' ')"/>
</zipCode>
</user>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当此转换应用于任何 XML 文档时 (未使用且实际上不需要,因为在 XSLT 2.0 中没有必要具有源 XML 文档),如果文件
C:\temp\delete\delete.txt
是 则 Testuser new_york 10018
usera seattle 98000
userb bellevue 98004
userb redmond 98052
再次生成想要的正确结果 :
<user>
<name>Testuser</name>
<city>new york</city>
<zipCode>10018</zipCode>
</user>
<user>
<name>usera</name>
<city>seattle</city>
<zipCode>98000</zipCode>
</user>
<user>
<name>userb</name>
<city>bellevue</city>
<zipCode>98004</zipCode>
</user>
<user>
<name>userb</name>
<city>redmond</city>
<zipCode>98052</zipCode>
</user>
注释 :
unparsed-text()
。 tokenize()
。 最后说明 :
大多数复杂的文本处理都是完全在 XSLT 中以工业方式完成的。 The FXSL library 包含一个通用的 LR(1) parser 和一个 tweaked YACC that produces XML-formatted tables ,它们是这个通用运行时 LR(1) 解析器的输入。
使用此工具,我成功地将 built parsers 用于 JSON 和 XPath 2.0 等复杂语言。
关于c# - xslt 是将文本转换为 xml 结构的好方法吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8205089/