使用 xslt 将文本转换为 xml
text to xml transforming using xslt
我有一个数据格式如下的文本文件:
FIRSTNAME
Jhon
Rembo
FIRSTNAME
James
KARL
LASTNAME
PAUL
SAM
BOND
我正在尝试使用 XSLT 2.0
将其转换为以下 XML 格式
<?xml version="1.0" encoding="UTF-8"?>
<customers>
<firstnames>
<firstname>Jhon</firstname>
<firstname>Rembo</firstname>
</firstnames>
<firstnames>
<firstname>James</firstname>
<firstname>KARL</firstname>
</firstnames>
<lastnames>
<lastname>PAUL</lastname>
<lastname>SAM</lastname>
<lastname>BOND</lastname>
</lastnames>
</customers>
如何获得 XML 结果的任何提示或示例。
编辑:
我已尝试使用以下 java 代码:
final String TXT_PATH = "D:/TXT_one.txt";
final String XSLT_PATH = "D:/XSLT_one.xslt";
final String XML_PATH = "D:/test_xml_result_one.xml";
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl();
Transformer transformer = tFactory.newTransformer(new StreamSource(new File(XSLT_PATH)));
transformer.transform(new StreamSource(new File(TXT_PATH)), new StreamResult(new File(XML_PATH)));
System.out.println("Output written to text file");
和 XSLT 文件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:my="my:my" exclude-result-prefixes="ext my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="lines" as="element()*">
<xsl:for-each select="tokenize(unparsed-text($input), '\r?\n')">
<line><xsl:value-of select="."/></line>
</xsl:for-each>
</xsl:variable>
<results>
<xsl:apply-templates select="$lines/*"/>
</results>
</xsl:template>
<xsl:template match="text()" name="group">
<xsl:param name="lines" select="."/>
<xsl:for-each-group select="$lines[normalize-space()]"
group-starting-with="*[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="remove(current-group(), 1)">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
编译错误如下:
Error at xsl:for-each on line 9 column 68 of XSLT_one.xslt:
XPST0008: Variable input has not been declared (or its declaration is
not in scope)
有什么方法可以将输入作为 txt 文件从 java class 传递?
您可以使用 XSLT2.0 中的未解析文本函数
先把线转成节点:
<xsl:variable name="lines" as="element()*">
<xsl:for-each select="tokenize(unparsed-text($input), '\r?\n')">
<line><xsl:value-of select="."/></line>
</xsl:for-each>
</xsl:variable>
然后将它们分组:
<xsl:for-each-group select="$lines[normalize-space()]"
group-starting-with="*[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="remove(current-group(), 1)">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
为了完整起见,XSLT 3.0 将其减少为:
<xsl:for-each-group
select="unparsed-text-lines($input)[normalize-space()]"
group-starting-with=".[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="tail(current-group())">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
我有一个数据格式如下的文本文件:
FIRSTNAME
Jhon
Rembo
FIRSTNAME
James
KARL
LASTNAME
PAUL
SAM
BOND
我正在尝试使用 XSLT 2.0
将其转换为以下 XML 格式<?xml version="1.0" encoding="UTF-8"?>
<customers>
<firstnames>
<firstname>Jhon</firstname>
<firstname>Rembo</firstname>
</firstnames>
<firstnames>
<firstname>James</firstname>
<firstname>KARL</firstname>
</firstnames>
<lastnames>
<lastname>PAUL</lastname>
<lastname>SAM</lastname>
<lastname>BOND</lastname>
</lastnames>
</customers>
如何获得 XML 结果的任何提示或示例。
编辑:
我已尝试使用以下 java 代码:
final String TXT_PATH = "D:/TXT_one.txt";
final String XSLT_PATH = "D:/XSLT_one.xslt";
final String XML_PATH = "D:/test_xml_result_one.xml";
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl();
Transformer transformer = tFactory.newTransformer(new StreamSource(new File(XSLT_PATH)));
transformer.transform(new StreamSource(new File(TXT_PATH)), new StreamResult(new File(XML_PATH)));
System.out.println("Output written to text file");
和 XSLT 文件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:my="my:my" exclude-result-prefixes="ext my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="lines" as="element()*">
<xsl:for-each select="tokenize(unparsed-text($input), '\r?\n')">
<line><xsl:value-of select="."/></line>
</xsl:for-each>
</xsl:variable>
<results>
<xsl:apply-templates select="$lines/*"/>
</results>
</xsl:template>
<xsl:template match="text()" name="group">
<xsl:param name="lines" select="."/>
<xsl:for-each-group select="$lines[normalize-space()]"
group-starting-with="*[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="remove(current-group(), 1)">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
编译错误如下:
Error at xsl:for-each on line 9 column 68 of XSLT_one.xslt:
XPST0008: Variable input has not been declared (or its declaration is not in scope)
有什么方法可以将输入作为 txt 文件从 java class 传递?
您可以使用 XSLT2.0 中的未解析文本函数
先把线转成节点:
<xsl:variable name="lines" as="element()*">
<xsl:for-each select="tokenize(unparsed-text($input), '\r?\n')">
<line><xsl:value-of select="."/></line>
</xsl:for-each>
</xsl:variable>
然后将它们分组:
<xsl:for-each-group select="$lines[normalize-space()]"
group-starting-with="*[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="remove(current-group(), 1)">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
为了完整起见,XSLT 3.0 将其减少为:
<xsl:for-each-group
select="unparsed-text-lines($input)[normalize-space()]"
group-starting-with=".[.=('FIRSTNAME', 'LASTNAME')]">
<xsl:element name="{lower-case(.)}s">
<xsl:for-each select="tail(current-group())">
<xsl:element name="{lower-case(current-group()[1])}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>