XSLT-将XML嵌套到CSV输出
我正在尝试使用XSLT将XML文件转换为CSV。我有以下要转换的XML文件(手动简化版本)。每个XML文件可以包含N个记录,其中N个可能不同XSLT-将XML嵌套到CSV输出,xml,csv,xslt,Xml,Csv,Xslt,我正在尝试使用XSLT将XML文件转换为CSV。我有以下要转换的XML文件(手动简化版本)。每个XML文件可以包含N个记录,其中N个可能不同 <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <reportheader> <name>REPORT 1&l
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<reportheader>
<name>REPORT 1</name>
<version>v1</version>
</reportheader>
<recordtype>
<account>
<accountname>B</accountname>
</account>
<record>
<time>12:00:00</time>
<qty>10</qty>
<price>20</price>
</record>
<record>
<time>16:00:00</time>
<qty>20</qty>
<price>10</price>
</record>
</recordtype>
<recordtype>
<account>
<accountname>A</accountname>
</account>
<record>
<time>16:00:00</time>
<qty>5</qty>
<price>10</price>
</record>
</recordtype>
</report>
我目前的方法是使用两个脚本。一个输出所有根节点和直接父节点的XSLT。在第二个XSLT中,我计算记录节点的数量,并在csv列名中循环N次。然后我寻找匹配/记录/时间[N]的示例。当前的方法大量借鉴了:
我目前的方法有两个问题。1,它假定每个记录始终具有每个可用字段。2.我无法为记录分配正确的帐户,因为100条记录可能只有6个帐户。它们在xml文件中“松散耦合”的方式使我的方法无效
有人能帮我找到一种更稳健、更高效的方法吗?提前感谢。您可以通过使用
祖先
轴查找近亲值一次完成
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:text>name|version|accountname|time|qty|price
</xsl:text>
<xsl:apply-templates select="//record"/>
</xsl:template>
<xsl:template match="record">
<xsl:value-of select="ancestor::report/reportheader/name"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="ancestor::report/reportheader/version"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="ancestor::recordtype/account/accountname"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="time"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="qty"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="price"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
名称|版本|账户名称|时间|数量|价格| xd
;
|
|
|
|
|
;
;
你也可以试试。
谢谢,我几乎可以无缝地调整这个答案,以适应扩展的用例。如果我可以问一个小的后续问题,我应该在哪里插入一个名称空间“x:”,以便它们与祖先轴查找一起工作?@GdvJ我想这只是祖先::x:name
对!我只需要记住在树中的每个元素前面加上“x:”,而不仅仅是在开头。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:text>name|version|accountname|time|qty|price
</xsl:text>
<xsl:apply-templates select="//record"/>
</xsl:template>
<xsl:template match="record">
<xsl:value-of select="ancestor::report/reportheader/name"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="ancestor::report/reportheader/version"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="ancestor::recordtype/account/accountname"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="time"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="qty"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="price"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<xsl:output method="text"/>
<xsl:template match="report">
<xsl:for-each select="reportheader">
<xsl:value-of select="name/local-name(),version/local-name(), following-sibling::recordtype[1]/account/accountname/local-name(),following-sibling::recordtype[1]/record[1]/time/local-name(),following-sibling::recordtype[1]/record[1]/qty/local-name(),following-sibling::recordtype[1]/record[1]/price/local-name()" separator="|"/>
</xsl:for-each>
<xsl:for-each select="recordtype/record">
<xsl:text>
</xsl:text>
<xsl:value-of select=" ancestor::report/reportheader/name,ancestor::report/reportheader/version, preceding-sibling::account/accountname,time,qty,price" separator="|"/>
</xsl:for-each>
</xsl:template>
You may also try it.