xsltkeytei

Copy over an XSLT attribute based on another attribute


It seems to me that this should be an easy thing to do with key but I'm struggling.

I have two XML files with <w> elements with <m> elements within.

They both have a @corresp attribute and a @sameAs attribute, but one of the files has is missing a number of the @sameAs attributes.

I would like to copy over the missing @sameAs attributes from one file to the other with the assumption that the @sameAs value is paired with the @corresp attribute's value (they are English/Spanish translations).

Where a value for @sameAs already exists, I this should not be overwritten.

The @sameAs - @corresp pairs are valid across both m and w.

The input file looks like this:

<p>
    <w  pos="N" corresp="house" sameAs="casa/ruca"><m corresp="house"  sameAs="casa" type="root">ruca</m></w>
    <w  pos="N" corresp="man"><m corresp="man" type="root">wentru</m></w>
    <w  pos="AJ" corresp="bad"><m corresp="bad" type="root">weda</m></w>
    <w  pos="N" corresp="query"><m corresp="stone/rock" sameAs="piedra/roca" type="root">cura</m><m corresp="instrumental" type="suffix">we</m></w>
</p>

The output should be:

<p>
    <w  pos="N" corresp="house" sameAs="casa/ruca"><m corresp="house" sameAs="casa" type="root">ruca</m></w>
    <w  pos="N" corresp="man"  sameAs="hombre"><m corresp="man" sameAs="hombre" type="root">wentru</m></w>
    <w  pos="AJ" corresp="bad"  sameAs="malo(a)"><m corresp="bad" type="root" sameAs="malo(a)">weda</m></w>
    <w  pos="N" corresp="query"><m corresp="stone/rock" sameAs="piedra/roca" type="root">kura</m><m corresp="instrumental" type="suffix">we</m></w>
</p>

The lookup file looks like this:

<p>
    <w  pos="N" corresp="house" sameAs="casa"><m corresp="house"  sameAs="casa" type="root">ruka</m></w>
    <w  pos="N" corresp="dog" sameAs="perro"><m corresp="dog"  sameAs="perro" type="root">txewa</m></w>
    <w  pos="N" corresp="man"  sameAs="hombre"><m corresp="man"  sameAs="hombre" type="root">wentro</m></w>
    <w  pos="AJ" corresp="bad"  sameAs="malo(a)"><m corresp="bad" type="root" sameAs="malo(a)">wesha</m></w>
    <w  pos="N" corresp="query"><m corresp="stone/rock" sameAs="piedra/roca" type="root">kura</m><m corresp="instrumental" type="suffix">we</m></w>
</p>

I tried the following, but to no avail:

<?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"
    xpath-default-namespace="http://www.tei-c.org/ns/1.0"
    exclude-result-prefixes="#all"
    version="3.0">
    <xsl:param name="lookup-doc" select="document('lookup.xml')"/>
    <xsl:key name="ref" match="w/@sameAs|node()" composite="yes" use="@corresp"/>
    <xsl:mode on-no-match="shallow-copy"/> 
    <xsl:template match="w/@sameAs|node()[key('ref', (@corresp, @sameAs), $lookup-doc)]">
        <xsl:copy-of select="w/@sameAs|node()[key('ref', (@corresp, @sameAs), $lookup-doc)]"/>
    </xsl:template>
</xsl:stylesheet>

Any tips?


Solution

  • The textual description to copy sameAs attributes if they don't exist sounds like

    <xsl:key name="ref" match="w" use="@corresp"/>
    
    <xsl:mode on-no-match="shallow-copy"/> 
    
    <xsl:template match="w[not(@sameAs)][key('ref', @corresp, $lookup-doc)] | m[not(@sameAs)][key('ref', @corresp, $lookup-doc)]">
        <xsl:copy>
          <xsl:apply-templates select="@*, key('ref', @corresp, $lookup-doc)/@sameAs, node()"/>
        </xsl:copy>
    </xsl:template>