的語句:(XSLT)"isn't suitable for transforming from structured text to XML. "
及本聲明"XSLT
must
have XML as the input document"
**都是錯誤。
我想2接近
定義的商業實體,並通過對輸入文本串功能填補了實體屬性,然後序列化實體 XML
預先定義xml結構,請使用xslt導航到每個節點並通過在輸入文本上使用子字符串函數來填充值。
事實上,方法2是很容易用XSLT來完成:
I. 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文檔(未使用和實際ñ OT需要,如在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>
注意:
使用標準的XSLT 2.0功能unparsed-text()
。
使用標準的XPath 2.0函數tokenize()
。
最後一點:
最複雜的文本處理已在工業方式XSLT已經做完全。 The FXSL library包含一個通用LR(1) parser和tweaked YACC that produces XML-formatted tables屬於輸入到該通用運行時LR(1)解析器。
使用此工具,我成功地爲built parsers對於像JSON和XPath 2.0這樣複雜的語言。
非常感謝你的想法。我將嘗試使用您建議的xslt庫,並看看它的熱點 – testuser