Копирование дочерних узлов одного узла в другой узел, но в отдельном узле на основе совпадения? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть требование скопировать дочерний узел от одного родителя к другому на основе соответствия сотрудника, но его нужно поместить в отдельный узел.Я почти получил решение, используя ключ, но я не могу вставить дочерний узел в новый отдельный узел.

Я разработал следующий код, используя функцию ключа:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="xs xsd"
version="2.0">

 <xsl:output indent="yes"/>
 <xsl:key name="kEmpID" match="wd:Worker_Data" 
 use="concat(ancestor::wd:LeaveStatus/wd:LeaveDetail,wd:EmpID)"/>

 <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
 </xsl:template>

<xsl:template match="wd:ChangeEvent/wd:EventDetails">
    <xsl:variable name="vLeaveStatus" 
 select="key('kEmpID',../wd:EmpID)"/>

   <xsl:copy>
        <xsl:apply-templates select="@*"/>
           <wd:Event>
               <xsl:apply-templates 
select="$vLeaveStatus/wd:LeaveStatus/wd:LeaveDetail/."/>
           </wd:Event>
    </xsl:copy>

</xsl:template>
</xsl:stylesheet>

Нижефактический ввод:

<?xml version='1.0' encoding='utf-8'?>
<wd:Census_Report xmlns:wd="urn:com.workday/bsvc">
<wd:Workers>
    <wd:Worker_Data>
        <wd:EmpID>50211</wd:EmpID>
        <wd:LeaveStatus>
            <wd:LeaveDetail>
                <wd:LOA_Start_Date>2017-12-22</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-01-22</wd:LOA_End_Date>
            </wd:LeaveDetail>
            <wd:LeaveDetail>
                <wd:LOA_Start_Date>2018-02-20</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-03-02</wd:LOA_End_Date>
            </wd:LeaveDetail>
        </wd:LeaveStatus>
    </wd:Worker_Data>
  </wd:Workers>
  <wd:ChangeEventSummary>       
    <wd:ChangeEvent>
        <wd:EmpID>50211</wd:EmpID>
        <wd:TermDate>2018-04-27</wd:TermDate>
        <wd:EventDetails/>
    </wd:ChangeEvent>
 </wd:ChangeEventSummary>
</wd:Census_Report>

Ниже приведен ожидаемый вывод:

<?xml version="1.0" encoding="UTF-8"?>
<wd:Census_Report xmlns:wd="urn:com.workday/bsvc">
<wd:Workers>
    <wd:Worker_Data>
        <wd:EmpID>50211</wd:EmpID>
        <wd:LeaveStatus>
            <wd:LeaveDetail>
                <wd:LOA_Start_Date>2017-12-22</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-01-22</wd:LOA_End_Date>
            </wd:LeaveDetail>
            <wd:LeaveDetail>
                <wd:LOA_Start_Date>2018-02-20</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-03-02</wd:LOA_End_Date>
            </wd:LeaveDetail>
        </wd:LeaveStatus>
    </wd:Worker_Data>
  </wd:Workers>
  <wd:ChangeEventSummary>       
    <wd:ChangeEvent>
        <wd:EmpID>50211</wd:EmpID>
        <wd:TermDate>2018-04-27</wd:TermDate>
        <wd:EventDetails>
        <wd:Event>
           <wd:LeaveDetail>
                <wd:LOA_Start_Date>2017-12-22</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-01-22</wd:LOA_End_Date>
            </wd:LeaveDetail>
        </wd:Event>
        <wd:Event>
           <wd:LeaveDetail>
                <wd:LOA_Start_Date>2018-02-20</wd:LOA_Start_Date>
                <wd:LOA_End_Date>2018-03-02</wd:LOA_End_Date>
            </wd:LeaveDetail>
        </wd:Event>
     </wd:EventDetails>
    </wd:ChangeEvent>
</wd:ChangeEventSummary>
</wd:Census_Report>

Я могу получить узел LeaveStatus в узел Event, но не получаюкак я могу держать каждый узел под LeaveStatus.

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

Почему вы не можете сделать просто:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday/bsvc">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="worker" match="wd:Worker_Data" use="wd:EmpID" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="wd:EventDetails">
    <xsl:copy>
        <xsl:for-each select="key('worker', ../wd:EmpID)/wd:LeaveStatus/wd:LeaveDetail">
            <wd:Event>
                <xsl:copy-of select="."/>
            </wd:Event>
         </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 06 мая 2019

Измените следующий код (из второго шаблона)

<xsl:copy>
  <xsl:apply-templates select="@*"/>
  <wd:Event>
    <xsl:apply-templates select="$vLeaveStatus/wd:LeaveStatus/wd:LeaveDetail/."/>
  </wd:Event>
</xsl:copy>

на

<xsl:copy>
  <xsl:apply-templates select="@*"/>
  <xsl:for-each select="$vLeaveStatus/wd:LeaveStatus/wd:LeaveDetail">
    <wd:Event>
      <wd:LeaveDetail>
        <xsl:apply-templates select="*"/>
      </wd:LeaveDetail>
    </wd:Event>
  </xsl:for-each>
</xsl:copy>

Тогда вы получите желаемый результат.

...