将元素转换为其父元素

时间:2017-09-22 14:24:00

标签: xml xslt xslt-2.0

我有XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
xmlns:pi="urn:com.workday/picof"
version="2.0">

<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <pi:Payroll_Extract_Employees>
        <xsl:copy-of select="//pi:Header"/>
        <xsl:for-each select="//pi:Employee">
        <pi:Employee>
            <xsl:copy-of select="pi:Summary"/>
        </pi:Employee>
        </xsl:for-each>
            <xsl:apply-templates select="//pi:Employee/pi:Additional_Information/*"/>
    </pi:Payroll_Extract_Employees>     
</xsl:template>

<xsl:template match="pi:Additional_Information/*">
    <xsl:apply-templates select="ancestor::pi:Payroll_Extract_Employees">
        <xsl:with-param name="UnpaidTO" select="current()"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="pi:Payroll_Extract_Employees">
    <xsl:param name="UnpaidTO"/>

    <pi:Time_Off>
        <pi:Code_Name>Unpaid Time Off</pi:Code_Name>
        <pi:Time_Off_Type><xsl:value-of select="substring-after(substring-before($UnpaidTO,'('),'=')"/></pi:Time_Off_Type>
        <pi:Time_Off_Date><xsl:value-of select="substring-before($UnpaidTO,',')"/></pi:Time_Off_Date>
        <pi:Quantity><xsl:value-of select="substring-before(substring-after($UnpaidTO,','),' ')"/></pi:Quantity>
        <pi:Unit_of_Time><xsl:value-of select="substring-after(substring-before($UnpaidTO,'='),' ')"/></pi:Unit_of_Time>
    </pi:Time_Off>

  </xsl:template>

  </xsl:stylesheet>

最初的XML:

<?xml version="1.0" encoding="UTF-8"?>
<pi:Payroll_Extract_Employees xmlns:pi="urn:com.workday/picof">
    <pi:Header>
        <pi:Updated_From>2017-09-07T02:23:04.000-07:00</pi:Updated_From>
    </pi:Header>
    <pi:Employee>
        <pi:Summary>
            <pi:Employee_ID>00000001</pi:Employee_ID>
        </pi:Summary>
        <pi:Additional_Information>
            <pi:Strike_1>2017-09-11,2 Hours=9570</pi:Strike_1>
        </pi:Additional_Information>
    </pi:Employee>
    <pi:Employee>
        <pi:Summary>
            <pi:Employee_ID>00000002</pi:Employee_ID>
        </pi:Summary>
        <pi:Additional_Information>
            <pi:Strike_1>2017-09-22,8 Hours=9570</pi:Strike_1>
            <pi:Unjustified_Absence_1>2017-09-25,8 Hours=9700</pi:Unjustified_Absence_1>
        </pi:Additional_Information>
    </pi:Employee>
</pi:Payroll_Extract_Employees>

我的代码运行良好。唯一的问题是转换后的元素(pi:Time_Off及其子元素)不是它们各自父节点的组(pi:Employee)

我希望最终结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<pi:Payroll_Extract_Employees xmlns:pi="urn:com.workday/picof">
    <pi:Header>
        <pi:Updated_From>2017-09-07T02:23:04.000-07:00</pi:Updated_From>
    </pi:Header>
    <pi:Employee>
        <pi:Summary>
            <pi:Employee_ID>00000001</pi:Employee_ID>
        </pi:Summary>
        <pi:Time_Off>
         <pi:Code_Name>Unpaid Time Off</pi:Code_Name>
         <pi:Time_Off_Type>9570</pi:Time_Off_Type>
         <pi:Time_Off_Date>2017-09-11</pi:Time_Off_Date>
         <pi:Quantity>2</pi:Quantity>
         <pi:Unit_of_Time>Hours</pi:Unit_of_Time>
        </pi:Time_Off>
    </pi:Employee>
    <pi:Employee>
        <pi:Summary>
           <pi:Employee_ID>00000002</pi:Employee_ID>
        </pi:Summary>
        <pi:Time_Off>
           <pi:Code_Name>Unpaid Time Off</pi:Code_Name>
           <pi:Time_Off_Type>9570</pi:Time_Off_Type>
           <pi:Time_Off_Date>2017-09-22</pi:Time_Off_Date>
           <pi:Quantity>8</pi:Quantity>
           <pi:Unit_of_Time>Hours</pi:Unit_of_Time>
        </pi:Time_Off>
        <pi:Time_Off>
           <pi:Code_Name>Unpaid Time Off</pi:Code_Name>
           <pi:Time_Off_Type>9700</pi:Time_Off_Type>
           <pi:Time_Off_Date>2017-09-25</pi:Time_Off_Date>
           <pi:Quantity>8</pi:Quantity>
           <pi:Unit_of_Time>Hours</pi:Unit_of_Time>
        </pi:Time_Off>
    </pi:Employee>
  </pi:Payroll_Extract_Employees>

我该怎么做才能让它像预期的结果一样?请帮我解决这个问题。非常感谢你!

1 个答案:

答案 0 :(得分:1)

问题在于这句话......

<xsl:apply-templates select="//pi:Employee/pi:Additional_Information/*"/>

首先它在Employees上的xsl:for-each之外,当它应该在它内部时(在pi:Employee元素的创建中)。

其次,//在开始时意味着它正在选择所有员工,而实际上您只需要相对于当前员工的表达式(即选择子Additional_Information元素)。

尝试使用此模板

<xsl:template match="/">
    <pi:Payroll_Extract_Employees>
        <xsl:copy-of select="//pi:Header"/>
        <xsl:for-each select="//pi:Employee">
        <pi:Employee>
            <xsl:copy-of select="pi:Summary"/>
            <xsl:apply-templates select="pi:Additional_Information/*"/>
        </pi:Employee>
        </xsl:for-each>
    </pi:Payroll_Extract_Employees>     
</xsl:template>