简体   繁体   中英

XSLT - Nested For-each with core-if

I want to remove the Resource nodes from the XML if they are not present in TaskLabor node using the resourceID attribute. I don't know how to access the variables inside for-each. can anyone please fix this?

I have provided the XSL transformation below. Instead of for-each, Can it be done using apply-templates?

Input XML:

<Project projectID="project1" name="My Project">
    <Resources>
        <Resource resourceID="abc@mycompany.com"/>
        <Resource resourceID="def@mycompany.com"/> <!-- Need to Remove this -->
        <Resource resourceID="xyz@mycompany.com"/>
        <Resource resourceID="test@mycompany.com"/> <!-- Need to Remove this -->
    </Resources>
    <Tasks>
        <Task name="Task1"
        taskID="100-150221">
            <Assignments>
                <TaskLabor finish="2020-12-31"
                   resourceID="abc@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
                <TaskLabor finish="2020-12-31"
                   resourceID="xyz@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
            </Assignments>
        </Task>
        <Task name="Task2"
        taskID="100-12313">
            <Assignments>
                <TaskLabor finish="2020-12-31"
                   resourceID="abc@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
            </Assignments>
        </Task>
    </Tasks>
</Project>

XSL Transformation:

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

    <xsl:template match="/">
        <xsl:variable name="resources" select="Project/Resources/Resource"/>
        <xsl:variable name="tasks" select="Project/Tasks/Task"/>
        <xsl:for-each select="$resources">
            <xsl:variable name="resID" select="./@resourceID"/>
            <xsl:for-each select="$tasks">
                <xsl:for-each select="./Assignments/TaskLabor">
                     <xsl:if test="$resID = ./@resourceID">
                        <xsl:value-of select="Project/Resources/Resource"/>

                     </xsl:if>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:for-each>
     </xsl:template>
</xsl:stylesheet>

Expected Output

<Project projectID="project1" name="My Project">
    <Resources>
        <Resource resourceID="abc@mycompany.com"/>
        <Resource resourceID="xyz@mycompany.com"/>
    </Resources>
    <Tasks>
        <Task name="Task1"
        taskID="100-150221">
            <Assignments>
                <TaskLabor finish="2020-12-31"
                   resourceID="abc@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
                <TaskLabor finish="2020-12-31"
                   resourceID="xyz@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
            </Assignments>
        </Task>
        <Task name="Task2"
        taskID="100-12313">
            <Assignments>
                <TaskLabor finish="2020-12-31"
                   resourceID="abc@mycompany.com"
                   start="2020-01-01">
                </TaskLabor>
            </Assignments>
        </Task>
    </Tasks>
</Project>

Declare a key <xsl:key name="task-ref" match="TaskLabor" use="@resourceID"/> and then you simply need to block elements which don't reference a TaskLabor from being copied by the identity transformation by using an empty template for them:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:key name="task-ref" match="TaskLabor" use="@resourceID"/>

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

  <xsl:template match="Resource[not(key('task-ref', @resourceID))]"/>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/3NSTbfg

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM