使用 XSLT 帮助将 XML 转换为 CSV [英] XML to CSV using XSLT help

查看:21
本文介绍了使用 XSLT 帮助将 XML 转换为 CSV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 XSLT 将 XML 转换为 CSV,但是当从名为 XML To CSV XSLT 针对我的输入:

<前><WhoisRecord><域名>127.0.0.1</域名><注册表数据><AbuseContact><电子邮件>abuse@iana.org</电子邮件><Name>Internet Corporation for Assigned Names and Number</Name><电话>+1-310-301-5820</电话></AbuseContact><AdministrativeContact i:nil="true"/><BillingContact i:nil="true"/><创建日期/><RawText>...</RawText><注册人><地址>4676 Admiralty Way, Suite 330</Address><City>Marina del Rey</City><国家>美国</国家><名称>互联网号码分配机构</名称><邮政编码>90292-6695</邮政编码><StateProv>CA</StateProv></注册人><技术联系方式><电子邮件>abuse@iana.org</电子邮件><Name>Internet Corporation for Assigned Names and Number</Name><电话>+1-310-301-5820</电话></技术联系人><更新日期>2010-04-14</更新日期><ZoneContact i:nil="true"/></RegistryData></WhoisRecord>

我最终得到:

abuse@iana.orgInternet Corporation for Assigned Names and Number+1-310-301-5820,,,,...,4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA,Abus@iana.org Internet Corporation for Assigned Names and Number+1-310-301-5820,2010-04-14,

我的问题是,由此产生的转换缺少节点(例如包含 IP 地址的 DomainName 元素),并且一些子节点没有逗号连接(例如 AbuseContact 的子节点).

我想查看 CSV 格式的所有 XML 输出,以及以下字符串:abuse@iana.orgInternet Corporation for Assigned Names and Number+1-310-301-5820",以逗号分隔.

我的 XSL 非常生疏.感谢您的帮助.:)

这是我使用的 XSL:

<前><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:模板></xsl:stylesheet>

解决方案

这个简单的转换产生了想要的结果:

<xsl:output method="text"/><xsl:strip-space elements="*"/><xsl:template match="/"><xsl:apply-templates select="//text()"/></xsl:模板><xsl:template match="text()"><xsl:copy-of select="."/><xsl:if test="not(position()=last())">,</xsl:if></xsl:模板></xsl:stylesheet>

注意的使用:

 

丢弃任何纯空白文本节点.

更新:AJ 提出了结果应该按每行记录/元组分组的问题.问题中没有定义记录/元组究竟应该是什么.因此,当前的解决方案解决了纯空白文本节点和缺少逗号两个问题,但并非旨在将输出抓取到记录/元组中.

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>abuse@iana.org</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>abuse@iana.org</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:

  abuse@iana.orgInternet Corporation for Assigned Names and Number+1-310-301-5820,
    ,
    ,
    ,
    ...,      
    4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA,      
    abuse@iana.orgInternet 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: "abuse@iana.orgInternet 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆