2011-12-22 31 views
1

我想在xml中遍历所有节点和子节点(递归)并将元素转换为txt格式。 E.g:使用xslt将所有xml元素转换为txt

<root> 
    <level> 
    <data1>data1</data1> 
    <sublevel> 
     <data2>data2</data2> 
    </sublevel> 
    </level> 
</root> 

我想txt格式的输出如下:

root 
    level 
    data1:data1 
    sublevel 
     data2:data2 

我目前的XSLT transormation是:

<xsl:strip-space elements="*" /> 

<xsl:template match="/"> 
    <xsl:for-each select="*"> 
    <xsl:value-of select="local-name()"/>: <xsl:value-of select="."/><xsl:text>&#xa;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

,但它不产生所需的输出。有一些错误:

  • 的元素的名称仅针对根节点转化
  • 有如果存在空元素(我想抑制空行)

感谢

空行

回答

0

用途:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="*"> 
     <xsl:value-of select="local-name()"/> 

     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="text()[normalize-space(.)]"> 
     <xsl:value-of select="concat(':', .)"/> 
    </xsl:template> 
</xsl:stylesheet> 

MSXSL输出:

root 
    level 
     data1:data1 
     sublevel 
      data2:data2 
+0

感谢基里尔,您的解决方案看起来不错,但我需要格式化输出(这是另一个要求)。输出的txt应该与输入的xml保持一致(请参阅我的问题:txt输出表示形式)。您示例中的输出全部被推入一行。你能告诉我如何格式化输出吗?谢谢。 – zosim 2011-12-22 10:14:39

+0

@zosim,我已经更新了我的答案。 – 2011-12-22 10:26:52

+0

@zosim,不要设置'' – 2011-12-22 10:27:38

0

尝试更换:

xsl:value-of select="local-name()" 

xsl:value-of select="text()" 

可以测试空值与if

<if test="text() = '' > 

我没有测试的代码,但应该给你一个想法。

0

下面可能是一个好推到正确的方向:输出需要缩进和子元素,不输出 - 但我猜你将能够弄清楚:-)。

<xsl:template match="/root"> 
    <xsl:call-template name="nodeToText"/> 
</xsl:template> 

<xsl:template name="nodeToText"> 
    <xsl:value-of select="local-name()"/>: <xsl:value-of select="."/><xsl:text>&#xa;</xsl:text> 
    <xsl:for-each select="child::*"> 
     <xsl:call-template name="nodeToText"/> 
    </xsl:for-each> 
</xsl:template> 

这导致了以下的输出:

root: data1data2 
level: data1data2 
data1: data1 
sublevel: data2 
data2: data2 
+0

谢谢,最后我用了Kirill的解决方案。 – zosim 2011-12-22 11:34:19