Re: [xsl] XPath to select based on attr = same attr of an ancestor

Subject: Re: [xsl] XPath to select based on attr = same attr of an ancestor
From: Hugh Cayless <hcayless@xxxxxxxxxxxxx>
Date: Sun, 13 Jul 2008 21:15:58 -0400
Hi Syd!

This seems to work:

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


  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="foreign">
    <xsl:variable name="lang" select="ancestor::*[@lang][1]/@lang"/>
    <xsl:choose>
      <xsl:when test="@lang != $lang">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

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

</xsl:stylesheet>

(if I've correctly understood the problem)

Cheers,
Hugh

/**
 * Hugh A. Cayless, Ph.D
 * Head, Research & Development Group
 * Carolina Digital Library and Archives
 * UNC Chapel Hill
 * hcayless@xxxxxxxxxxxxx
 */






On Jul 13, 2008, at 8:46 PM, Syd Bauman wrote:


The idea here is that I want a template that will match any <foreign>
element that has a lang= attribute with a value that matches the
lang= attribute value of said <foreign> element's nearest ancestor
that has a lang= attribute specified. (So that I can delete said
<foreign>.) I.e. in

  <div lang="en">
    <p>Only <foreign lang="en">one</foreign> more!</p>
    <p>Only <foreign lang="es">uno</foreign> more!</p>
  </div>

the first <foreign> should be matched, and the second should not.
Thus the above should become

  <div lang="en">
    <p>Only one more!</p>
    <p>Only <foreign lang="es">uno</foreign> more!</p>
  </div>

I used the following XPath on the match= of an <xsl:template>:
foreign[@lang][ancestor::*[@lang]][1][ ./@lang = ./ancestor::*[@lang] [1]/@lang ]
While my stylesheet seems to work for simple cases, it fails for many
cases, too. (Like missing all but the 1st <foreign> in a <p>.)


In case it helps, I have made the requisite files available via the
web (see below), but it may be the case that sharp eyes here can pick
up on some detail I've messed up just by looking at the XPath itself.
And while I'd prefer to stick with XSLT 1 and thus XPath 1, XSLT 2
and thus XPath 2 is an option.

1) the story:
   http://bauman.zapto.org/~syd/temp/rrfq/story.txt
2) the XSLT 1.0 stylesheet itself
   http://bauman.zapto.org/~syd/temp/rrfq/remove_redundant_foreign_elements.xslt
3) a test input XML file
   http://bauman.zapto.org/~syd/temp/rrfq/test_remove_redundant_foreign_input.xml
4) the desired output
   http://bauman.zapto.org/~syd/temp/rrfq/test_remove_redundant_foreign_desired.xml
5) the actual output
   http://bauman.zapto.org/~syd/temp/rrfq/test_remove_redundant_foreign_output.xml

Current Thread