问题描述
我想使用XSLT将XML转换为CSV,但是当从SO线程应用XSL时,标题为对我的输入:
< WhoisRecord>
< DomainName> 127.0.0.1< / DomainName>
< RegistryData>
< AbuseContact>
< Email> [email protected]< / Email>
< Name>互联网名称和号码的公司< / Name>
< Phone> + 1-310-301-5820< / Phone>
< / AbuseContact>
< AdministrativeContact i:nil =true/>
< BillingContact i:nil =true/>
< CreatedDate />
< RawText> ...< / RawText>
<注册人>
< Address> 4676 Admiralty Way,Suite 330< / Address>
< City> Marina del Rey< / City>
< Country> US< / Country>
< Name>互联网号码分配机构< / Name>
< PostalCode> 90292-6695< / PostalCode>
< StateProv> CA< / StateProv>
< / Registrant>
< TechnicalContact>
< Email> [email protected]< / Email>
< Name>互联网名称和号码的公司< / Name>
< Phone> + 1-310-301-5820< / Phone>
< / TechnicalContact>
< UpdatedDate> 2010-04-14< / UpdatedDate>
< ZoneContact i:nil =true/>
< / RegistryData>
< / WhoisRecord>
我最后得到:
[email protected]互联网公司指定名称和编号+ 1-310-301-5820,
,
,
,
...,
4676海军部Way,Suite 330Marina del ReyUSInternet分配号码Authority90292-6695CA,
[email protected]互联网公司指定姓名和号码+ 1-310-301-5820,
2010-04-14,
我的问题是,所产生的转换是缺少节点(如DomainName元素包含IP地址)和一些子节点
我想以CSV形式查看所有XML输出,以及如下字符串:abuse @ iana。 orgInternet Corporation for Assigned Names and Number + 1-310-301-5820,用逗号分隔。
我的XSL很生锈。您的帮助是赞赏。 :)
这里是我使用的XSL:
< xsl :stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transform>
< xsl:output method =textencoding =iso-8859-1/>
< xsl:strip-space elements =*/>
< xsl:template match =/ * / child :: *>
< xsl:for-each select =child :: *>
< xsl:if test =position()!= last()>< xsl:value -of select =normalize-space(。)/> ;,< / xsl:if> ;
< xsl:if test =position()= last()>< xsl:value -of select =normalize-space(。)/>< xsl:text& xD;< / xsl:text>
< / xsl:if>
< / xsl:for-each>
< / xsl:template>
< / xsl:stylesheet>
解决方案 这个简单的转换产生想要的结果:
< xsl:stylesheet version =1.0
xmlns:xsl =http://www.w3.org/ 1999 / XSL / Transform>
< xsl:output method =text/>
< xsl:strip-space elements =*/>
< xsl:template match =/>
< xsl:apply-templates select =// text()/>
< / xsl:template>
< xsl:template match =text()>
< xsl:copy-of select =。/>
< xsl:if test =not(position()= last())>,< / xsl:if>
< / xsl:template>
< / xsl:stylesheet>
请注意使用:
< xsl:strip-space elements =*/>
舍弃任何纯白色文本节点。
更新:AJ提出了结果以每行的recirds / tuples分组的问题。在问题中没有定义什么是记录/元组应该是什么。因此,当前的解决方案解决了白色空间文本节点和缺少逗号的两个问题,但是不打算将输出扩展到记录/元组中。
I'd like to convert XML into CSV using an XSLT, but when applying the XSL from the SO thread titled XML To CSV XSLT against my input:
<WhoisRecord>
<DomainName>127.0.0.1</DomainName>
<RegistryData>
<AbuseContact>
<Email>[email protected]</Email>
<Name>Internet Corporation for Assigned Names and Number</Name>
<Phone>+1-310-301-5820</Phone>
</AbuseContact>
<AdministrativeContact i:nil="true"/>
<BillingContact i:nil="true"/>
<CreatedDate/>
<RawText>...</RawText>
<Registrant>
<Address>4676 Admiralty Way, Suite 330</Address>
<City>Marina del Rey</City>
<Country>US</Country>
<Name>Internet Assigned Numbers Authority</Name>
<PostalCode>90292-6695</PostalCode>
<StateProv>CA</StateProv>
</Registrant>
<TechnicalContact>
<Email>[email protected]</Email>
<Name>Internet Corporation for Assigned Names and Number</Name>
<Phone>+1-310-301-5820</Phone>
</TechnicalContact>
<UpdatedDate>2010-04-14</UpdatedDate>
<ZoneContact i:nil="true"/>
</RegistryData>
</WhoisRecord>
I end up with:
[email protected] Corporation for Assigned Names and Number+1-310-301-5820,
,
,
,
...,
4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA,
[email protected] Corporation for Assigned Names and Number+1-310-301-5820,
2010-04-14,
My problem is that, the resulting transformation is missing nodes (like the DomainName element containing the IP address) and some child nodes are concatenated without commas (like the children of AbuseContact).
I'd like to see all the XML output in CSV form, and strings like: "[email protected] Corporation for Assigned Names and Number+1-310-301-5820," delimited by commas.
My XSL is pretty rusty. Your help is appreciated. :)
Here's the XSL I'm using:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()"><xsl:value-of select="normalize-space(.)"/>, </xsl:if>
<xsl:if test="position() = last()"><xsl:value-of select="normalize-space(.)"/><xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
解决方案 This simple transformation produces the wanted result:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//text()"/>
</xsl:template>
<xsl:template match="text()">
<xsl:copy-of select="."/>
<xsl:if test="not(position()=last())">,</xsl:if>
</xsl:template>
</xsl:stylesheet>
Do note the use of:
<xsl:strip-space elements="*"/>
to discard any white-space-only text nodes.
Update: AJ raised the problem that the results shoud be grouped in recirds/tuples per line. It isn't defined in the question what a record/tuple should exactly be. Therefore the current solution solves the two problems of white-space-only text nodes and of missing commas, but does not aim to grop the output into records/tuples.
这篇关于使用XSLT帮助将XML转换为CSV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!