简体   繁体   中英

XSLT copy element to another according to attribute value

I need to copy a node according to an attribute in another node in the same element. An example input XML is as follows:

<?xml version="1.0"?>
<Company>
    <Department id="Marketing">
        <depName>Marketing</depName>
        <position>Marketer</position>
    </Department>
    <Employee id="e1" level="l1">
        <First>John</First>
        <Dep code="Marketing"></Dep>
    </Employee>
    <Employee id="e2" level="l1">
        <First>Jane</First>
        <Dep code="Marketing"></Dep>
    </Employee>
    <Boss id="e3" level="l2">
        <First>Ben</First>
        <Dep code="Marketing"></Dep>
    </Boss>
</Company>

The output XML should look as follows:

<?xml version="1.0"?>
<Company>
    <Department id="Marketing">
        <depName>Marketing</depName>
        <position>Marketer</position>
    </Department>
    <Employee id="e1" level="l1">
        <First>John</First>
        <Dep code="Marketing"></Dep>
        <position>Marketer</position>
    </Employee>
    <Employee id="e2" level="l1">
        <First>Jane</First>
        <Dep code="Marketing"></Dep>
        <position>Marketer</position>
    </Employee>
    <Boss id="e3" level="l2">
        <First>Ben</First>
        <Dep code="Marketing"></Dep>
    </Boss>
</Company>

Of course there can be many more employees and departments. I need to copy the position element from the Department to each of the Employees that work in the Department (eg for Marketing have <Dep code="Marketing"> ), but not to the Bosses . The department can be checked using its id attribute or depName element, they should be identical.

I'm new to an XSLT so just have a basic idea how to select the element but don't really know how to go on from here (copy it to the correct place):

<xsl:template match="Department">
    <xsl:copy>
        <xsl:copy-of select="position"/>
    </xsl:copy>
</xsl:template>

Edit: Added attributes to employees, they need to be retained in the output

Declare a key

<xsl:key name="dep" match="Department" use="@id"/>

and then write the template for Employee

<xsl:template match="Employee">
  <xsl:copy>
     <xsl:copy-of select="@*, node(), key('dep', Dep/@code)/position"/>
  </xsl:copy>
</xsl:template>

The comma operator , is availble with XSLT 2 or 3 processors, for an XSLT 1 processor use two separate

<xsl:copy-of select="@* | node()"/>
<xsl:copy-of select="key('dep', Dep/@code)/position"/>

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