XML to csv 做正确的 xslt

Posted

技术标签:

【中文标题】XML to csv 做正确的 xslt【英文标题】:XML to csv do the correct xslt 【发布时间】:2019-12-17 21:51:51 【问题描述】:

我有一个大的 xml 文件,但我没有找到正确的方法来执行正确的 xslt 以根据需要输出 csv 文件。

我尝试了一些 xslt,但没有找到正确的输出。

XML 输入格式为:

<?xml version="1.0" encoding="UTF-8"?>
<CONSOLIDATED_LIST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://test/test.xsd" dateGenerated="2015-08-03T19:03:43.593-04:00">
    <INDIVIDUALS>
        <INDIVIDUAL><DATAID>13</DATAID><VERSIONNUM>4</VERSIONNUM><FIRST_NAME> TEST </FIRST_NAME><SECOND_NAME> TEST</SECOND_NAME><THIRD_NAME/><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>10-12-1978</LISTED_ON><COMMENTS1>
</COMMENTS1><DESIGNATION><VALUE></VALUE></DESIGNATION><NATIONALITY><VALUE></VALUE></NATIONALITY><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><INDIVIDUAL_ALIAS><QUALITY/><ALIAS_NAME/></INDIVIDUAL_ALIAS><INDIVIDUAL_ADDRESS><COUNTRY/></INDIVIDUAL_ADDRESS><INDIVIDUAL_DATE_OF_BIRTH><TYPE_OF_DATE></TYPE_OF_DATE><DATE>1964-07-17</DATE></INDIVIDUAL_DATE_OF_BIRTH><INDIVIDUAL_PLACE_OF_BIRTH/><INDIVIDUAL_DOCUMENT><TYPE_OF_DOCUMENT></TYPE_OF_DOCUMENT><NUMBER></NUMBER></INDIVIDUAL_DOCUMENT><SORT_KEY/><SORT_KEY_LAST_MOD/></INDIVIDUAL>
</INDIVIDUALS> 
<ENTITIES>
<ENTITY><DATAID></DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME></FIRST_NAME><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>1952-12-31</LISTED_ON><COMMENTS1></COMMENTS1><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><ENTITY_ALIAS><QUALITY/><ALIAS_NAME/></ENTITY_ALIAS><ENTITY_ADDRESS><CITY></CITY><COUNTRY></COUNTRY></ENTITY_ADDRESS><SORT_KEY/><SORT_KEY_LAST_MOD/>
</ENTITY>
</ENTITIES>
</CONSOLIDATED_LIST>     

预期结果是一个用标题分隔的 csv 分号: 例子: 个人

Dataid;Versionnum;First_Name;Second_Name;Third_Name;Un_List_Type;Reference_Number;Listed_On;Comments1;Designation;Nationality;List_Type;Last_Day_Updated;Individual_Alias;Quality;Alias_Name;Individual_Address;Country;Individual_Date_Of_Bird;Individal_Place_Of_Birth;Type_Of_Date;Date;Individual_Place_Of_Birth;Individual_Document;Type_Of_Document;Number;Sort_Key;Sort_Key_Last_Mod
13;4; TEST ; TEST ;;;10-12-1978;;;;;;;;;;;;;;;;;1964-07-17;;;;;;;;;

在这个标题下是标签内的数据,底部或其他文件中

实体

Dataid;VersionNum;First_Name;Un_List_Type;Reference_Number;Listed_On;Comments1;List_Type;Last_Day_Updated;Entity_Alias;Quality;Alias_Name;Entity_Address;City;Country;Sort_Key;Sort_Key_Last_Mod;
;;1;;;;;;1952-12-31;;;;;;;;;;;;

原始xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<CONSOLIDATED_LIST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://test/test.xsd" dateGenerated="2018-08-08T19:03:43.593-04:00">
    <INDIVIDUALS>
        <INDIVIDUAL><DATAID>6</DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME> TEST </FIRST_NAME><SECOND_NAME> TEST </SECOND_NAME><THIRD_NAME> TEST <THIRD_NAME/><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>1936-11-30</LISTED_ON><COMMENTS1></COMMENTS1><DESIGNATION><VALUE></VALUE></DESIGNATION><NATIONALITY><VALUE></VALUE></NATIONALITY><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><INDIVIDUAL_ALIAS><QUALITY/><ALIAS_NAME/></INDIVIDUAL_ALIAS><INDIVIDUAL_ADDRESS><COUNTRY/></INDIVIDUAL_ADDRESS><INDIVIDUAL_DATE_OF_BIRTH><TYPE_OF_DATE></TYPE_OF_DATE><DATE>1964-07-17</DATE></INDIVIDUAL_DATE_OF_BIRTH><INDIVIDUAL_PLACE_OF_BIRTH/><INDIVIDUAL_DOCUMENT><TYPE_OF_DOCUMENT>Passport</TYPE_OF_DOCUMENT><NUMBER></NUMBER></INDIVIDUAL_DOCUMENT><SORT_KEY/><SORT_KEY_LAST_MOD/></INDIVIDUAL>
        <INDIVIDUAL><DATAID>6</DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME> TEST1</FIRST_NAME><SECOND_NAME> TEST1 </SECOND_NAME><THIRD_NAME/> TEST1 <THIRD_NAME/><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>1921-11-30</LISTED_ON><COMMENTS1/><DESIGNATION><VALUE></VALUE></DESIGNATION><NATIONALITY><VALUE></VALUE></NATIONALITY><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><INDIVIDUAL_ALIAS><QUALITY></QUALITY><ALIAS_NAME></ALIAS_NAME></INDIVIDUAL_ALIAS><INDIVIDUAL_ADDRESS><COUNTRY/></INDIVIDUAL_ADDRESS><INDIVIDUAL_DATE_OF_BIRTH><TYPE_OF_DATE>EXACT</TYPE_OF_DATE><DATE>1964-01-10</DATE></INDIVIDUAL_DATE_OF_BIRTH><INDIVIDUAL_PLACE_OF_BIRTH/><INDIVIDUAL_DOCUMENT/><SORT_KEY/><SORT_KEY_LAST_MOD/></INDIVIDUAL>
</INDIVIDUALS>
<ENTITIES>
<ENTITY><DATAID>6</DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME> TEST ENTITY </FIRST_NAME> <SECOND_NAME> ENTITY TEST </SECOND_NAME><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>1931-03-30</LISTED_ON><COMMENTS1></COMMENTS1><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE>2014-05-23</VALUE></LAST_DAY_UPDATED><ENTITY_ALIAS><QUALITY/><ALIAS_NAME/></ENTITY_ALIAS><ENTITY_ADDRESS><STREET></STREET><CITY></CITY><ZIP_CODE></ZIP_CODE><COUNTRY></COUNTRY></ENTITY_ADDRESS><SORT_KEY/><SORT_KEY_LAST_MOD/></ENTITY>
</ENTITIES>
</CONSOLIDATED_LIST>

已修改的 XSL 示例仅获得一项,而不是标签中的所有项。 我希望所有“个人”和所有“实体”都声明了子数据。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:variable name="separator" select="'&#59;'" />
    <xsl:variable name="newline" select="'&#10;'" />

    <xsl:template match="/">
        <xsl:text>Individuals:</xsl:text>
        <xsl:text>DataID;First_Name;Second_Name;Third_Name</xsl:text>
        <xsl:value-of select="$newline" />
        <xsl:for-each select="//INDIVIDUALS">
            <xsl:value-of select="INDIVIDUAL/DATAID" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/FIRST_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/SECOND_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/THIRD_NAME" />
            <xsl:value-of select="$newline" />
            <xsl:value-of select="INDIVIDUAL/DATAID" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/FIRST_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/SECOND_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="INDIVIDUAL/THIRD_NAME" />
            <xsl:value-of select="$newline" />
    </xsl:for-each>
    </xsl:template>
  <xsl:template1 match="/">
        <xsl:text>Entities:</xsl:text>
        <xsl:text>First_Name;Second_Name;Third_Name</xsl:text>
        <xsl:value-of select="$newline" />
        <xsl:for-each select="//ENTITIES">
            <xsl:value-of select="ENTITY/FIRST_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="ENTITY/SECOND_NAME" />
            <xsl:value-of select="$separator" />
            <xsl:value-of select="ENTITY/THIRD_NAME" />
            <xsl:value-of select="$newline" />
</xsl:for-each>
    </xsl:template1>
</xsl:stylesheet>

做: xslproc origin.xml test.xsl 结果:

Individuals:
DataID;First_Name;Second_Name;Third_Name
6; TEST ; TEST ;; TEST 
6; TEST ; TEST ;; TEST 

预期结果是:

Individuals:
DataID;First_Name;Second_Name;Third_Name
6; TEST ; TEST ; TEST 
6; TEST1 ; TEST1 ; TEST1 
Entities:
First_Name;Second_Name;Third_Name
TEST ENTITY ; ENTITY TEST  ;; 

更新:

在回答xsl的测试中 输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<CONSOLIDATED_LIST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://test/test.xsd" dateGenerated="2012-08-08T19:03:43.593-04:00">
    <INDIVIDUALS>
        <INDIVIDUAL><DATAID>5</DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME> TEST </FIRST_NAME><SECOND_NAME>TEST1</SECOND_NAME><THIRD_NAME/><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>2016-11-30</LISTED_ON><COMMENTS1></COMMENTS1><DESIGNATION><VALUE></VALUE></DESIGNATION><NATIONALITY><VALUE></VALUE></NATIONALITY><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><INDIVIDUAL_ALIAS><QUALITY/><ALIAS_NAME/></INDIVIDUAL_ALIAS><INDIVIDUAL_ADDRESS><COUNTRY/></INDIVIDUAL_ADDRESS><INDIVIDUAL_DATE_OF_BIRTH><TYPE_OF_DATE>EXACT</TYPE_OF_DATE><DATE>1964-07-17</DATE></INDIVIDUAL_DATE_OF_BIRTH><INDIVIDUAL_PLACE_OF_BIRTH/><INDIVIDUAL_DOCUMENT><TYPE_OF_DOCUMENT></TYPE_OF_DOCUMENT><NUMBER></NUMBER></INDIVIDUAL_DOCUMENT><SORT_KEY/><SORT_KEY_LAST_MOD/></INDIVIDUAL>
        <INDIVIDUAL><DATAID></DATAID><VERSIONNUM></VERSIONNUM><FIRST_NAME>TEST</FIRST_NAME><SECOND_NAME>TEST2</SECOND_NAME><THIRD_NAME/><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>2016-11-30</LISTED_ON><COMMENTS1/><DESIGNATION><VALUE></VALUE></DESIGNATION><NATIONALITY><VALUE></VALUE></NATIONALITY><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><INDIVIDUAL_ALIAS><QUALITY></QUALITY><ALIAS_NAME></ALIAS_NAME></INDIVIDUAL_ALIAS><INDIVIDUAL_ADDRESS><COUNTRY/></INDIVIDUAL_ADDRESS><INDIVIDUAL_DATE_OF_BIRTH><TYPE_OF_DATE></TYPE_OF_DATE><DATE>1964-01-10</DATE></INDIVIDUAL_DATE_OF_BIRTH><INDIVIDUAL_PLACE_OF_BIRTH/><INDIVIDUAL_DOCUMENT/><SORT_KEY/><SORT_KEY_LAST_MOD/></INDIVIDUAL>
</INDIVIDUALS>
 <ENTITIES>
        <ENTITY><DATAID></DATAID><VERSIONNUM>1</VERSIONNUM><FIRST_NAME> TEST
</FIRST_NAME><UN_LIST_TYPE></UN_LIST_TYPE><REFERENCE_NUMBER></REFERENCE_NUMBER><LISTED_ON>2012-09-11</LISTED_ON><COMMENTS1></COMMENTS1><LIST_TYPE><VALUE></VALUE></LIST_TYPE><LAST_DAY_UPDATED><VALUE/></LAST_DAY_UPDATED><ENTITY_ALIAS><QUALITY/><ALIAS_NAME/></ENTITY_ALIAS><ENTITY_ADDRESS><CITY>Pyongyang</CITY><COUNTRY></COUNTRY></ENTITY_ADDRESS><SORT_KEY/><SORT_KEY_LAST_MOD/></ENTITY>
   </ENTITIES>
</CONSOLIDATED_LIST>

输出:

First_Name;Second_Name;Third_Name
 TEST ;TEST1;;
TEST;TEST2;;
Entities:
First_Name;Second_Name;Third_Name
 TEST
;;

【问题讨论】:

您应该添加 xslt 代码并用它描述您的问题:D @Lety 我已经测试了很多 xslt 方法,但没有选择一种我所有的尝试都是错误的。 试试***.com/questions/365312/xml-to-csv-using-xslt或***.com/questions/46151921/…或***.com/questions/41544616/…或***.com/questions/7077920/… 我不知道我的 xsltproc 版本的结果是否被认为是一个原因,但并非所有示例都比我在堆栈中查看过的所有示例都运行良好.. 我会去测试你的链接,谢谢,测试了第一个并且有效。我认为原因是不是所有的 xml 输入都是相同的:甚至不知道是否所有标签上的大写在解析问题里面。 【参考方案1】:

这仍然很混乱。试试这个作为你的起点:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/CONSOLIDATED_LIST">
    <!-- INDIVIDUALS -->
    <!-- header -->
    <xsl:text>Individuals:&#10;DataID;First_Name;Second_Name;Third_Name&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="INDIVIDUALS/INDIVIDUAL">
        <xsl:value-of select="DATAID"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="FIRST_NAME"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="SECOND_NAME"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="THIRD_NAME" />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
    <!-- ENTITIES -->
    <!-- header -->
    <xsl:text>Entities:&#10;Dataid;VersionNum;First_Name&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="ENTITIES/ENTITY">
        <xsl:text>;</xsl:text>
        <xsl:value-of select="DATAID"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="VERSIONNUM"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="FIRST_NAME" />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

【讨论】:

如果我需要两个不同的输出文件:Individualsout 和 Entitiesout,是否可以解析 1 次 xsl 并在此解析中执行 2 个输出文件?或者我需要重新解析 xml 文件,并将 for-each 分隔在其他 xsl 中? @User1234141414 如果您使用xsltproc,您可能可以使用exsl:document 扩展元素:exslt.org/exsl/elements/document/index.html 否则您将需要调用转换两次(使用两个不同的 XSLT 样式表) 或迁移到 XSLT 2.0 处理器。 o @michael.hor257k 好的,其他问题,如果标签内有一个新行,输出也会将新行添加到最终输出,它没有一些规范化里面的新行标签? 恐怕我不明白你在问什么。提出一个新问题可能会更好,minimal reproducible example 会显示问题。 P.S.如果此问题得到解答,请通过接受答案来关闭它。

以上是关于XML to csv 做正确的 xslt的主要内容,如果未能解决你的问题,请参考以下文章

转换块引用并正确列出 XSLT [关闭]

使用 xslt 将 json 转换为 csv

如何在 XSLT 表中显示正确的内容

使用 XSLT 将 CSV 文件转换为 XML

XML 到 CSV 使用 XSLT 帮助

如何编写 XSLT 将 XML 转换为 CSV?