You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改XSLT实现XML转CSV时Position-Nbr列为首列

需求实现方案

需求概述

现有XML数据源及XSLT转换脚本,用于生成CSV文件。headerFieldsMap节点定义CSV表头,psPositions节点存储业务数据。需调整XSLT逻辑,确保当headerFieldsMap中包含PositionNbr节点时,其对应的表头文本“Position-Nbr”固定为CSV的第一列。

原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>
  </headerFieldsMap>
  <psPositions>
    <position>
      <LocationPostal>06511</LocationPostal>
      <ConfidentialFlag>N</ConfidentialFlag>
      <DeptDescr>New Haven EMU Shop</DeptDescr>
      <Description>Carman E Rate</Description>
      <RegTemp>R</RegTemp>
      <SalAdminPlan>TWUR</SalAdminPlan>
      <JobCodeSetid>SHARE</JobCodeSetid>
      <LocationCountry>US</LocationCountry>
      <Remote>N</Remote>
      <Step>0</Step>
      <SalaryRangeTo>0</SalaryRangeTo>
      <PositionNbr>01000333</PositionNbr>
      <SalaryRangeFrom>0</SalaryRangeFrom>
      <EffStatus>A</EffStatus>
      <FullPartTime>F</FullPartTime>
      <PositionStatus>Approved</PositionStatus>
      <LocationSetId>SHARE</LocationSetId>
      <CompanyName>Metro-North Railroad</CompanyName>
      <RemainingHeadCount>0</RemainingHeadCount>
      <PayFrequency>H</PayFrequency>
      <JobCode>26448E</JobCode>
      <RegRegion>USA</RegRegion>
      <Shift>2</Shift>
      <ReportsToPos>01000474</ReportsToPos>
      <DeptIdSetId>MNCRR</DeptIdSetId>
      <TotalWorkingHours>40</TotalWorkingHours>
      <DescrShort>Carman E R</DescrShort>
      <StdHoursFreq>W</StdHoursFreq>
      <LocationCode>NEW HAVEN</LocationCode>
      <Effdt>2023-02-21</Effdt>
      <LocationDescr>98 Union Street</LocationDescr>
      <LocationCity>New Haven</LocationCity>
      <Grade>004</Grade>
      <JobFamily>Transportation Operations</JobFamily>
      <DeptId>44302</DeptId>
      <LastUpdDtTm>2023-02-21T19:12:05Z</LastUpdDtTm>
      <LocationRegion>CT</LocationRegion>
      <ReportsToEmail>Burns@mnr.org</ReportsToEmail>
      <PayCurrency>USD</PayCurrency>
      <MaxHeadCount>1</MaxHeadCount>
      <BusinessUnit>MNCRR</BusinessUnit>
      <JobFamilyCode>TRNOPS</JobFamilyCode>
      <CompanyCode>MNR</CompanyCode>
      <CurrHeadCount>1</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:variable name="targetField" select="'PositionNbr'"/>

    <xsl:template match="/root">
        <!-- 表头行处理 -->
        <!-- 优先输出Position-Nbr表头(仅当存在时) -->
        <xsl:if test="headerFieldsMap/*[local-name()=$targetField]">
            <xsl:value-of select="headerFieldsMap/*[local-name()=$targetField]"/>
            <!-- 若还有其他字段,添加分隔符 -->
            <xsl:if test="count(headerFieldsMap/*) > 1">
                <xsl:value-of select="$delimiter"/>
            </xsl:if>
        </xsl:if>
        <!-- 输出剩余表头(排除PositionNbr) -->
        <xsl:for-each select="headerFieldsMap/*[local-name()!=$targetField]">
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">
                <xsl:value-of select="$delimiter"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>

        <!-- 数据行处理 -->
         <xsl:for-each select="psPositions/position">
            <xsl:variable name="row" select="."/>
            <!-- 优先输出PositionNbr数据(仅当表头包含该字段时) -->
            <xsl:if test="/root/headerFieldsMap/*[local-name()=$targetField]">
                <xsl:value-of select="$row/*[local-name()=$targetField]"/>
                <!-- 若还有其他字段,添加分隔符 -->
                <xsl:if test="count(/root/headerFieldsMap/*) > 1">
                    <xsl:value-of select="$delimiter"/>
                </xsl:if>
            </xsl:if>
            <!-- 输出剩余数据(排除PositionNbr),保留原有转换逻辑 -->
            <xsl:for-each select="/root/headerFieldsMap/*[local-name()!=$targetField]">
                <xsl:variable name="fieldName" select="local-name()"/>

                <xsl:choose>
                    <xsl:when test="$row/*[local-name()=$fieldName] = 'W' and $fieldName = 'StdHoursFreq'">
                        <xsl:text>Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$row/*[local-name()=$fieldName] = 'B' and $fieldName = 'StdHoursFreq'">
                        <xsl:text>Bi-Weekly</xsl:text>
                    </xsl:when>
                    <xsl:when test="$row/*[local-name()=$fieldName] = '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="$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>

修改说明

  1. 表头逻辑调整:先判断PositionNbr是否存在,存在则优先输出其表头,再遍历输出剩余表头字段
  2. 数据行逻辑同步:对应表头顺序,先输出PositionNbr的数据,再按剩余表头顺序输出对应数据
  3. 兼容性保留:如果headerFieldsMap中没有PositionNbr节点,转换逻辑自动退化为原有行为,不影响其他场景

转换结果示例

Position-Nbr,Business Unit Code,Business Unit Desct,Department Description,Department,Posting Job Title,Working Position Description,Category,Standard hours Frequency,Standard Hours
01000333,MNCRR,Metro-North Railroad,New Haven EMU Shop,44302,Carman E Rate,Carman E Rate,Transportation Operations,Weekly,40

内容的提问来源于stack exchange,提问作者Dark Matter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:47:06