XML转换为CSV,所有子级都排成一行

时间:2019-01-14 15:16:54

标签: xslt

如何将以下XML导出到CSV并将子级放在同一行:

<?xml version="1.0" encoding="UTF-8"?>
<NetworkEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="3.0">
    <Location>
        <SureName>9143146669213334465</SureName>
        <Type>Location</Type>
        <SubType>Rack</SubType>
        <DisplayName>NAME/O2OR_HUIB_04 / O2OR_HUIN_04 - IP DSLAM Type 5 - Model B</DisplayName>
        <Category>INFRASTRUCTURE</Category>
        <Features>
            <Feature>
                <Name>Site</Name>
                <Value>NAME</Value>
                <DisplayName>Site</DisplayName>
                <Discovered>true</Discovered>
            </Feature>
        </Features>
        <Associations>
            <Association>
                <Target xsi:type="Location">
                    <SureName>9143101104413609244</SureName>
                </Target>
                <Type>
                    <Type>ASSOCIATES_WITH</Type>
                </Type>
            </Association>
        </Associations>
    </Location>
</NetworkEntity>

我设法将其导出,但是我没有添加其余的内容:

SureName,Type,SubType,DisplayName,Category,Name,Value,Discovered
9143146669213334465,Location,Rack,NAME/O2OR_HUIB_04 / O2OR_HUIN_04 - IP DSLAM Type 5 - Model B,INFRASTRUCTURE,,,
9143147170713655610,Location,Rack,NAME/12PT_HUIB_06 / 12PT_HUIN_06 - IP DSLAM Type 5 - Model B,INFRASTRUCTURE,,,
9143147288813732088,Location,Rack,NAME/74GW_HUIB_04 / 74GW_HUIN_04 - IP DSLAM Type 5 - Model B,INFRASTRUCTURE,,,
9143155460813423214,Location,Rack,NAME/O2HX_HUIB_02 / O2HX_HUIN_02 - IP DSLAM Type 5 - Model B,INFRASTRUCTURE,,,

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:variable name="delimiter" select="','" />
<!-- define an array containing the fields we are interested in -->

<xsl:variable name="mainAttributesArray">
    <field>SureName</field>
    <field>Type</field>
    <field>SubType</field>
    <field>DisplayName</field>
    <field>Category</field>
    <field>Name</field> 
    <field>Value</field>    
    <field>Discovered</field>
</xsl:variable>

<xsl:param name="fields" select="document('')/*/xsl:variable[@name='mainAttributesArray']/*" />

<xsl:template match="/">
  <!-- output the header row -->
  <xsl:for-each select="$fields">
    <xsl:if test="position() != 1">
      <xsl:value-of select="$delimiter"/>
    </xsl:if>
    <xsl:value-of select="." />
  </xsl:for-each>
  <!-- output newline -->
  <xsl:text>
</xsl:text>
  <xsl:apply-templates select=".//NetworkEntity/Location"/>
</xsl:template>

<xsl:template match="Location">
  <xsl:variable name="currNode" select="." />
  <!-- output the data row -->
  <!-- loop over the field names and find the value of each one in the xml -->
  <xsl:for-each select="$fields">
    <xsl:if test="position() != 1">
      <xsl:value-of select="$delimiter"/>
    </xsl:if>
    <xsl:value-of select="$currNode/*[name() = current()]" />
    <xsl:for-each select="Features/Feature">
    <xsl:text>test</xsl:text>
        <xsl:value-of select="name()" />
    </xsl:for-each>

  </xsl:for-each>
<!-- output newline -->
  <xsl:text>&#xa;</xsl:text>
</xsl:template>
</xsl:stylesheet>

预期结果:

SureName,Type,SubType,DisplayName,Category,Name,Value,Discovered,AssociationTarget,AssociationSureName,AssociationType
9143146669213334465,Location,Rack,NAME/O2OR_HUIB_04 / O2OR_HUIN_04 - IP DSLAM Type 5 - Model B,INFRASTRUCTURE,Site,NAME,Site,True,Location,9143101104413609244,ASSOCIATES_WITH

谢谢!

1 个答案:

答案 0 :(得分:0)

您为什么不简单做:

XSLT 1.0

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

<xsl:template match="/NetworkEntity">
    <!-- header (Location + Features + Associations) -->
    <xsl:text>SureName,Type,SubType,DisplayName,Category,</xsl:text>
    <xsl:text>Name,Value,Discovered,</xsl:text>
    <xsl:text>AssociationTarget,AssociationSureName,AssociationType&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="Location">
        <!-- Location -->
        <xsl:value-of select="SureName"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Type"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="SubType"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="DisplayName"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Category"/>
        <xsl:text>,</xsl:text>
        <!-- Features -->       
        <xsl:value-of select="Features/Feature/Name"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Features/Feature/Value"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Features/Feature/Discovered"/>
        <xsl:text>,</xsl:text>
        <!-- Associations -->
        <xsl:value-of select="Associations/Association/Target/@xsi:type"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Associations/Association/Target/SureName"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Associations/Association/Type/Type"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

请注意,我们在这里假设每个Location最多具有一个Feature和一个Association-但是您的XML的结构允许每个都有多个实例。