我必须使用XSLT 2.0读取文本文件并输出XML。输入文本文件如:
Start:000,A:123,B:234,C:33,End:99,Start:03,A:123d,B:234s,End:992,Start:a00,B:234,C:33,End:99
所需的XML输出如下:
<File>
<Rec>
<Start>000</Start>
<A>123</A>
<B>234</B>
<C>33</C>
<End>99</End>
</Rec>
<Rec>
<Start>03</Start>
<A>123d</A>
<B>234s</B>
<End>992</End>
</Rec>
<Rec>
<Start>a00</Start>
<B>234</B>
<C>33</C>
<End>99</End>
</Rec>
我很难将元素从“开始”分组到“结束”并向其添加父元素“Rec”。有什么建议吗?非常感谢!
答案 0 :(得分:3)
您可以使用unparsed-text()
和tokenize()
来创建您正在寻找的输出。如果文本文件可能包含多行,您也可以使用xsl:analyze-string
。
示例...
文字输入(so.txt)
Start:000,A:123,B:234,C:33,End:99,Start:03,A:123d,B:234s,End:992,Start:a00,B:234,C:33,End:99
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="input-encoding" as="xs:string" select="'iso-8859-1'"/>
<xsl:param name="input-uri" as="xs:string" select="'so.txt'"/>
<xsl:template match="/">
<xsl:variable name="input" select="unparsed-text($input-uri, $input-encoding)"/>
<File>
<xsl:analyze-string select="$input" regex="\r\n?|\n">
<xsl:non-matching-substring>
<xsl:for-each select="tokenize(.,'Start')[string()]">
<Rec>
<xsl:for-each select="tokenize(.,',')[string()]">
<xsl:variable name="vals" select="tokenize(.,':')"/>
<xsl:element name="{if (position()=1) then 'Start' else $vals[1]}">
<xsl:value-of select="$vals[2]"/>
</xsl:element>
</xsl:for-each>
</Rec>
</xsl:for-each>
</xsl:non-matching-substring>
</xsl:analyze-string>
</File>
</xsl:template>
</xsl:stylesheet>
XML输出
<File>
<Rec>
<Start>000</Start>
<A>123</A>
<B>234</B>
<C>33</C>
<End>99</End>
</Rec>
<Rec>
<Start>03</Start>
<A>123d</A>
<B>234s</B>
<End>992</End>
</Rec>
<Rec>
<Start>a00</Start>
<B>234</B>
<C>33</C>
<End>99</End>
</Rec>
</File>
答案 1 :(得分:0)
我会通过标记化,然后分组来实现。
<xsl:variable name="raw" as="element()*">
<xsl:for-each select="tokenize(normalize-space(unparsed-text('input.txt')), ',')">
<xsl:element name="{substring-before(., ':')}">
<xsl:value-of select="substring-after(., ':')"/>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<File>
<xsl:for-each-group select="$raw" group-starting-with="Start">
<Rec>
<xsl:copy-of select="current-group()"/>
</Rec>
</xsl:for-each-group>
</File>