使用一些过滤器将 XML 转换为 CSV

问题描述 投票:0回答:1

我有一个 XML,我正在尝试将其转换为带有某些过滤器的 CSV。我的 CSV 标题在下面,只有标题值应该出现在下面的数据中。所有这些都在使用我的 XSLT。但是,我在一个字段上有一个过滤器,当字段名称为“StdHoursFreq”且其值为“W”时,Weekly 应该出现在数据中。但出于某种原因,它正在为所有值为“W”的字段进行转换。 XML 版本为 1.0

这里是带有 1 个数据行的 XML 以保持简单

<root>
  <headerFieldsMap>
    <BusinessUnit>Business Unit Code</BusinessUnit>
    <CompanyName>Business Unit Desct</CompanyName>
    <DeptDescr>Department Description</DeptDescr>
    <DeptId>Department</DeptId>
    <DescrShort>Posting Job Title</DescrShort>
    <Description>Working Position Description</Description>
    <JobFamily>Category</JobFamily>
    <PositionNbr>Position-Nbr</PositionNbr>
    <StdHoursFreq>Standard hours Frequency</StdHoursFreq>
    <TotalWorkingHours>Standard Hours</TotalWorkingHours>
    <PayFrequency>Pay</PayFrequency>
  </headerFieldsMap>
  <psPositions>
    <position>
      <PayFrequency>W</PayFrequency>
      <LocationPostal>10520</LocationPostal>
      <ConfidentialFlag>N</ConfidentialFlag>
      <DeptDescr>Structures H&amp;H Facilities</DeptDescr>
      <Description>Plumber - Structures</Description>
      <RegTemp>R</RegTemp>
      <SalAdminPlan>SMWI</SalAdminPlan>
      <JobCodeSetid>SHARE</JobCodeSetid>
      <LocationCountry>US</LocationCountry>
      <Remote>N</Remote>
      <Step>0</Step>
      <SalaryRangeTo>0</SalaryRangeTo>
      <PositionNbr>01000000</PositionNbr>
      <SalaryRangeFrom>0</SalaryRangeFrom>
      <EffStatus>A</EffStatus>
      <FullPartTime>F</FullPartTime>
      <PositionStatus>Approved</PositionStatus>
      <LocationSetId>SHARE</LocationSetId>
      <CompanyName>Metro-North Railroad</CompanyName>
      <RemainingHeadCount>-4</RemainingHeadCount>
      <PayFrequency>H</PayFrequency>
      <JobCode>25580E</JobCode>
      <RegRegion>USA</RegRegion>
      <Shift>1</Shift>
      <ReportsToPos>01005484</ReportsToPos>
      <DeptIdSetId>MNCRR</DeptIdSetId>
      <TotalWorkingHours>40</TotalWorkingHours>
      <DescrShort>Plumber -</DescrShort>
      <StdHoursFreq>W</StdHoursFreq>
      <LocationCode>HARMON</LocationCode>
      <Effdt>2020-05-04</Effdt>
      <LocationDescr>Harmon</LocationDescr>
      <LocationCity>Croton-on-Hudson</LocationCity>
      <Grade>007</Grade>
      <JobFamily>Craft Jobs</JobFamily>
      <DeptId>59201</DeptId>
      <LastUpdDtTm>2020-05-04T20:24:38Z</LastUpdDtTm>
      <LocationRegion>NY</LocationRegion>
      <ReportsToEmail>[email protected]</ReportsToEmail>
      <PayCurrency>USD</PayCurrency>
      <MaxHeadCount>1</MaxHeadCount>
      <BusinessUnit>MNCR</BusinessUnit>
      <JobFamilyCode>CRFTJB</JobFamilyCode>
      <CompanyCode>MNR</CompanyCode>
      <CurrHeadCount>5</CurrHeadCount>
     </position>
    </psPositions>
</root>

这是我的 XSLT

<?xml version="1.0"?>
               <xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:req="http://peoplesoft.com/requestResponse"
                xmlns:csl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>

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

    <xsl:template match="/root">
        <!-- Header row -->
        <xsl:for-each select="headerFieldsMap/*">
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">
                <xsl:value-of select="$delimiter"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>

        <!-- Data rows -->
         <xsl:for-each select="psPositions/position">
            <xsl:variable name="row" select="."/>
            <xsl:for-each select="/root/headerFieldsMap/*">
                <xsl:variable name="fieldName" select="local-name()"/>
                <xsl:variable name="fieldValue" select="."/>

                <!-- If the field value is StdHoursFreq and it's equal to "W", replace it with "Weekly" -->
                <xsl:choose>
                    <xsl:when test="$row/*[local-name()=$fieldName] = 'W' and $row/*[local-name()='StdHoursFreq']">
                        <xsl:text>Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$row/*[local-name()=$fieldName] = 'B' and $row/*[local-name()='StdHoursFreq']">
                        <xsl:text>Bi-Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$row/*[local-name()=$fieldName] = 'M' and $row/*[local-name()='StdHoursFreq']">
                        <xsl:text>Monthly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$fieldName = 'DescrShort'">
                        <xsl:value-of select="$row/*[local-name()='Description']"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$row/*[local-name()=$fieldName]"/>
                    </xsl:otherwise>
                </xsl:choose>

                <xsl:if test="position() != last()">
                    <xsl:value-of select="$delimiter"/>
                </xsl:if>
            </xsl:for-each>
            <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

这是输出

Business Unit Code,Business Unit Desct,Department Description,Department,Posting Job Title,Working Position Description,Category,Position-Nbr,Standard hours Frequency,Standard Hours,Pay
MNCR,Metro-North Railroad,Structures H&H Facilities,59201,Plumber - Structures,Plumber - Structures,Craft Jobs,01000000,Weekly,40,Weekly

正如您在输出中看到的那样,它也将 Pay 或 PayFrequency 的值返回为 Weekly。它应该只将 StdHoursFreq 的值返回为每周。为什么它映射不正确?

xml csv xslt xslt-1.0
1个回答
0
投票

请尝试以下解决方案。

不清楚为什么需要这么多命名空间声明。您输入的 XML 没有。

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:req="http://peoplesoft.com/requestResponse"
                xmlns:csl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="/root">
        <!-- Header row -->
        <xsl:for-each select="headerFieldsMap/*">
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">
                <xsl:value-of select="$delimiter"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>

        <!-- Data rows -->
        <xsl:for-each select="psPositions/position">
            <xsl:variable name="row" select="."/>
            <xsl:for-each select="/root/headerFieldsMap/*">
                <xsl:variable name="fieldName" select="local-name()"/>
                <xsl:variable name="fieldValue" select="$row/*[local-name()=$fieldName]/text()"/>

                <!-- If the field value is StdHoursFreq and it's equal to "W", replace it with "Weekly" -->
                <xsl:choose>
                    <xsl:when test="$fieldValue = 'W' and $fieldName='StdHoursFreq'">
                        <xsl:text>Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$fieldValue = 'B' and $fieldName='StdHoursFreq'">
                        <xsl:text>Bi-Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$fieldValue = 'M' and $fieldName='StdHoursFreq'">
                        <xsl:text>Monthly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$fieldName = 'DescrShort'">
                        <xsl:value-of select="$row/*[local-name()='Description']"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$fieldValue"/>
                    </xsl:otherwise>
                </xsl:choose>

                <xsl:if test="position() != last()">
                    <xsl:value-of select="$delimiter"/>
                </xsl:if>
            </xsl:for-each>
            <xsl:text>&#xA;
            </xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

输出

Business Unit Code,Business Unit Desct,Department Description,Department,Posting Job Title,Working Position Description,Category,Position-Nbr,Standard hours Frequency,Standard Hours,Pay
MNCR,Metro-North Railroad,Structures H&H Facilities,59201,Plumber - Structures,Plumber - Structures,Craft Jobs,01000000,Weekly,40,W

        
© www.soinside.com 2019 - 2024. All rights reserved.