2012-11-27 72 views
0

我想从以下形式的XML文件进行CSV创建CSV:如何使用XSLT从XML

<?xml version="1.0" encoding="UTF-8"?> 
    <Envelope> 
     <Header> 
      <env:MessageSentDateTime>2012-09-19T09:50:04Z</env:MessageSentDateTime> 
      <env:MessageSequenceNumber>856432</env:MessageSequenceNumber> 
     </Header> 
     <Body> 
      <Data> 
       <Data:ID> 
        <Data:AODB>9346280</Data:AODB> 
        <Data:Ref> 
         <common:Code>HJ</common:Code> 
         <common:num>8113</common:num> 
        </Data:Ref> 
       </Data:ID> 
       ... Continues like this, no set number of nodes, parts or AnotherParts 
     </Body> 
     Second message starting with <Header> ending with </Body>, 
     will be more than 2 in practice 
    </Envelope> 

我想提出一个换行符CSV文件在/身体标签因为这表示一条新消息。在正文部分中会有不同数量的节点,不同数量的部分和不一致的末端节点的消息混合。另外,将会有不包含任何文本的节点,但我仍然需要逗号。

到目前为止,我有:

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output method="text"/> 
     <xsl:strip-space elements="*"/> 

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

     <xsl:template match="Body[last()]"> 
      <xsl:value-of select="normalize-space(.)"/> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:template> 
    </xsl:stylesheet> 

它还在机身的最后一条信息后加逗号。我想用换行符替换那个逗号,有没有简单的方法来做到这一点?

问候, 大卫

+0

试试这个:http://stackoverflow.com/questions/3056579/convert-xml-document-to-comma-delimited-csv-file-using-xslt-stylesheet –

回答

0

我的规格略有改变,需要的节点路径和值,以使每个条目唯一的。这是我用来解决我的问题的代码:

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"></xsl:output> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*[*]"> 
     <xsl:param name="elementNames" select="''"/> 
     <xsl:apply-templates select="*"> 
      <xsl:with-param name="elementNames"> 
       <xsl:copy-of select="$elementNames"/> 
       <xsl:value-of select="replace(name(.), ':', '.')"/> 
       <xsl:text>_</xsl:text> 
      </xsl:with-param> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="*[not (*)]"> 
     <xsl:param name="elementNames" select="''"/> 
     <xsl:copy-of select="$elementNames"/> 
     <xsl:value-of select="replace(name(.), ':', '.')"/> 
     <xsl:value-of select="name()"/>,<xsl:apply-templates select="current()/text()"/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="/*"> 
      <xsl:apply-templates select="*"/> 
    </xsl:template> 
    </xsl:stylesheet> 

谢谢大家谁看了,并试图帮助。

问候, 大卫

0

一种方法可以更改模板的身体元件匹配具体来看为“叶”的子元素

<xsl:template match="Body"> 
    <xsl:apply-templates select=".//*[not(*)]"/> 
    <xsl:text>&#10;</xsl:text> 
</xsl:template> 

然后,在你的模板匹配叶子元素,如果它不是第一个元素,则可以将其更改为仅输出逗号

<xsl:if test="position() &gt; 1"> 
    <xsl:text>,</xsl:text> 
    </xsl:if> 

下面是完整的XSLT,如果你想给它一个去:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*[not(*)]"> 
     <xsl:if test="position() &gt; 1"> 
     <xsl:text>,</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="normalize-space(.)"/> 
    </xsl:template> 

    <xsl:template match="Body"> 
     <xsl:apply-templates select=".//*[not(*)]"/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 
+0

喜添C,谢谢你的回复。这段代码用最后的逗号排序问题,但它不会在输出中给我一个新行 –

+0

您可以尝试在XSLT中用'NEWLINE'替换' ',因为这将证明模板匹配** Body * *实际上正在使用。另外,如果你编辑你的问题来显示一个XML实例的完整例子(虽然不是太大!),它会有所帮助。谢谢! –

+0

我试着用NEWLINE替换,模板没有被使用。我用一些实际的xml数据编辑了这个问题 –