使用XSLT多节点的XML到CSV

时间:2014-07-04 11:54:37

标签: xml xslt csv

我正在尝试使用XSLT将xml文件转换为CSV格式。 我的XML文件有多个根(Account),包含属性,也有不同类型的子。

这是我的XML:

<SiebelMessage>
<ListOfSwiOrganizationIO>
    <Account>
        <Email>jozk8o@sk.ibm.com</Email>
        <Name>ESET</Name>
        <Address>
            <StreetAddress>Vodna 9</StreetAddress>
            <City>Nitra</City>
        </Address>
        <Contact>
            <LastName>Jozo</LastName>
            <FirstName>Sekera</FirstName>
        </Contact>
        <AccountCategory>
            <CategoryValue>90</CategoryValue>
        </AccountCategory>
        <AccountCategory>
            <CategoryValue>91</CategoryValue>
        </AccountCategory>
        <IntegrityCode>
            <IntegrityType>AllowSms</IntegrityType>
            <ConsentCode>YES</ConsentCode>
        </IntegrityCode>
        <IntegrityCode>
            <IntegrityType>AllowEmail</IntegrityType>
            <ConsentCode>YES</ConsentCode>
        </IntegrityCode>
    </Account>
    <Account>
        <Email>ferk8o@sk.ibm.com</Email>
        <Name>IBM</Name>
        <Address>
            <StreetAddress>Dlha 1</StreetAddress>
            <City>Bratislava</City>
        </Address>
        <Contact>
            <LastName>Fero</LastName>
            <FirstName>Kopacka</FirstName>
        </Contact>
        <AccountCategory>
            <CategoryValue>90</CategoryValue>
        </AccountCategory>
        <AccountCategory>
            <CategoryValue>91</CategoryValue>
        </AccountCategory>
        <IntegrityCode>
            <IntegrityType>AllowSms</IntegrityType>
            <ConsentCode>YES</ConsentCode>
        </IntegrityCode>
        <IntegrityCode>
            <IntegrityType>AllowEmail</IntegrityType>
            <ConsentCode>YES</ConsentCode>
        </IntegrityCode>
    </Account>
</ListOfSwiOrganizationIO>

我能够根据这里的一些文章创建XSLT,但只显示没有子项的根属性。

必需的输出是:

Email;Name;StreetAddress;City;LastName;FirstName;CategoryValue;AllowSms;AllowEmail
jozk8o@sk.ibm.com;ESET;Vodna 9;Nitra;Jozo;Sekera;90,91;YES;NOTSET
ferk8o@sk.ibm.com;IBM;Dlha 1;Bratislava;Fero;Kopacka;90,91;YES;NO

这是我目前的XSLT:

<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="delimiter" select="';'"/>
<xsl:template match="/">
<!-- Output the CSV header -->
<xsl:text>Email;Name;StreetAddress;City;LastName;FirstName;CategoryValue;AllowSms;AllowEmail&#10;</xsl:text> 
<!-- Output the values -->
<xsl:for-each select="SiebelMessage/ListOfSwiOrganizationIO/Account">
    <!-- begin values -->
    <xsl:value-of select="concat(Email, $delimiter, Name, $delimiter, ListOfAddress/Address/StreetAddress, $delimiter, ListOfAddress/Address/City, $delimiter, Contact/LastName, $delimiter, Contact/FirstName, $delimiter)"/>
    <!-- Category Values -->
    <xsl:for-each select="AccountCategory">
        <xsl:value-of select="CategoryValue"/>
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text> 
        </xsl:if>
    </xsl:for-each>
    <xsl:value-of select="$delimiter"/>
    <!-- Integrity Codes -->
    <xsl:value-of select="concat(IntegrityCode[IntegrityType='AllowSms']/ConsentCode, $delimiter, IntegrityCode[IntegrityType='AllowEmail']/ConsentCode)"/>
    <xsl:choose>
          <xsl:when test="ConsentCode=YES">
             (1)
          </xsl:when>
       </xsl:choose>
    <!-- end values -->
    <xsl:if test="position()!=last()">
        <xsl:text>&#10;</xsl:text> 
    </xsl:if>
</xsl:for-each>

您能否建议如何实施儿童? 我目前的输出只是:

EMAIL;NAME
jozk8o@sk.ibm.com;ESET;
ferk8o@sk.ibm.com;IBM;

非常感谢

1 个答案:

答案 0 :(得分:0)

如果结构是常数并且事先已知,我建议您通过命名输入元素明确来构建输出:

XSLT 1.0
(已修改以匹配更新的问题)

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

<xsl:variable name="delimiter" select="';'"/>

<xsl:template match="/">
    <!-- Output the CSV header -->
    <xsl:text>Email;Name;StreetAddress;City;LastName;FirstName;CategoryValue;AllowSms;AllowEmail&#10;</xsl:text> 
    <!-- Output the values -->
    <xsl:for-each select="SiebelMessage/ListOfSwiOrganizationIO/Account">
        <!-- begin values -->
        <xsl:value-of select="concat(Email, $delimiter, Name, $delimiter, Address/StreetAddress, $delimiter, Address/City, $delimiter, Contact/LastName, $delimiter, Contact/FirstName, $delimiter)"/>
        <!-- Category Values -->
        <xsl:for-each select="AccountCategory">
            <xsl:value-of select="CategoryValue"/>
            <xsl:if test="position()!=last()">
                <xsl:text>,</xsl:text> 
            </xsl:if>
        </xsl:for-each>
        <xsl:value-of select="$delimiter"/>
        <!-- Integrity Codes -->
        <xsl:value-of select="concat(IntegrityCode[IntegrityType='AllowSms']/ConsentCode, $delimiter, IntegrityCode[IntegrityType='AllowEmail']/ConsentCode)"/>
        <!-- end values -->
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text> 
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这具有速度和没有不必要的“移动部件”的优点。