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: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sun, 13 Jul 2008 22:56:48 -0400
At 2008-07-13 20:46 -0400, 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>.)

Below is a solution "syd.xsl" that uses a modification of your input that includes French for testing purposes.


It reads: match="foreign[@lang=ancestor::*[@lang][1]/@lang]"

       "match the foreign element whose lang attribute is equal to
        the lang attribute of the closest ancestor with a lang
        attribute"

I've also included a solution that uses xml:lang= instead of lang= since there are more semantics for xml:lang= ... for example, in the third test the xml:lang= of the document is a subset of the xml:lang= of the embedded content. I don't know if this will be of help or not (in fact, it might be backwards from what you need and not of any use).

I hope this helps.

. . . . . . . . . . . . Ken

t:\ftemp>type test_remove_redundant_foreign_input.xml
<?xml version="1.0" encoding="UTF-8"?>
<test lang="en">
<p>This is a <foreign lang="en">test</foreign> of the non-<foreign lang="en">emergency</foreign> element tag-removal <foreign lang="en">system</foreign>. This is only a <foreign lang="en">test</foreign>.</p>
<p>
<list>
<item><foreign lang="en">one</foreign></item>
<item><foreign lang="en">two</foreign></item>
<item><foreign lang="en">three</foreign></item>
<item><foreign lang="en">four</foreign></item>
</list>
</p>
<p>
<foreign lang="en">one</foreign>
<foreign lang="en">two</foreign>
<foreign lang="en">three</foreign>
<foreign lang="en">four</foreign>
<foreign lang="fr">un</foreign>
<foreign lang="fr">deux</foreign>
<foreign lang="fr">trois</foreign>
<foreign lang="fr">quatre</foreign>
</p>
</test>


t:\ftemp>type syd.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

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

<xsl:template match="foreign[@lang=ancestor::*[@lang][1]/@lang]">
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>call xslt test_remove_redundant_foreign_input.xml syd.xsl result.xml

t:\ftemp>type result.xml
<?xml version="1.0" encoding="utf-8"?><test lang="en">
<p>This is a test of the non-emergency element tag-removal system. This is only a test.</p>
<p>
<list>
<item>one</item>
<item>two</item>
<item>three</item>
<item>four</item>
</list>
</p>
<p>
one
two
three
four
<foreign lang="fr">un</foreign>
<foreign lang="fr">deux</foreign>
<foreign lang="fr">trois</foreign>
<foreign lang="fr">quatre</foreign>
</p>
</test>
t:\ftemp>type test_remove_redundant_foreign_input2.xml
<?xml version="1.0" encoding="UTF-8"?>
<test xml:lang="en">
<p>This is a <foreign xml:lang="en">test</foreign> of the non-<foreign xml:lang="en">emergency</foreign> element tag-removal <foreign xml:lang="en">system</foreign>. This is only a <foreign xml:lang="en">test</foreign>.</p>
<p>
<list>
<item><foreign xml:lang="en">one</foreign></item>
<item><foreign xml:lang="en">two</foreign></item>
<item><foreign xml:lang="en">three</foreign></item>
<item><foreign xml:lang="en">four</foreign></item>
</list>
</p>
<p>
<foreign xml:lang="en">one</foreign>
<foreign xml:lang="en">two</foreign>
<foreign xml:lang="en">three</foreign>
<foreign xml:lang="en">four</foreign>
<foreign xml:lang="fr">un</foreign>
<foreign xml:lang="fr">deux</foreign>
<foreign xml:lang="fr">trois</foreign>
<foreign xml:lang="fr">quatre</foreign>
</p>
</test>


t:\ftemp>type syd2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

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

<xsl:template match="foreign[lang(ancestor::*[@xml:lang][1]/@xml:lang)]">
  <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>call xslt test_remove_redundant_foreign_input2.xml syd2.xsl result2.xml


t:\ftemp>type result2.xml
<?xml version="1.0" encoding="utf-8"?><test xml:lang="en">
<p>This is a test of the non-emergency element tag-removal system. This is only a test.</p>
<p>
<list>
<item>one</item>
<item>two</item>
<item>three</item>
<item>four</item>
</list>
</p>
<p>
one
two
three
four
<foreign xml:lang="fr">un</foreign>
<foreign xml:lang="fr">deux</foreign>
<foreign xml:lang="fr">trois</foreign>
<foreign xml:lang="fr">quatre</foreign>
</p>
</test>
t:\ftemp>type test_remove_redundant_foreign_input3.xml
<?xml version="1.0" encoding="UTF-8"?>
<test xml:lang="fr">
<p>This is a <foreign xml:lang="en">test</foreign> of the non-<foreign xml:lang="en">emergency</foreign> element tag-removal <foreign xml:lang="en">system</foreign>. This is only a <foreign xml:lang="en">test</foreign>.</p>
<p>
<list>
<item><foreign xml:lang="en">one</foreign></item>
<item><foreign xml:lang="en">two</foreign></item>
<item><foreign xml:lang="en">three</foreign></item>
<item><foreign xml:lang="en">four</foreign></item>
</list>
</p>
<p>
<foreign xml:lang="en">one</foreign>
<foreign xml:lang="en">two</foreign>
<foreign xml:lang="en">three</foreign>
<foreign xml:lang="en">four</foreign>
<foreign xml:lang="fr-ca">un</foreign>
<foreign xml:lang="fr-ca">deux</foreign>
<foreign xml:lang="fr-ca">trois</foreign>
<foreign xml:lang="fr-ca">quatre</foreign>
</p>
</test>


t:\ftemp>call xslt test_remove_redundant_foreign_input3.xml syd2.xsl result3.xml

t:\ftemp>type result3.xml
<?xml version="1.0" encoding="utf-8"?><test xml:lang="fr">
<p>This is a <foreign xml:lang="en">test</foreign> of the non-<foreign xml:lang="en">emergency</foreign> element tag-removal <foreign xml:lang="en">system</foreign>. This is only a <foreign xml:lang="en">test</foreign>.</p>
<p>
<list>
<item><foreign xml:lang="en">one</foreign></item>
<item><foreign xml:lang="en">two</foreign></item>
<item><foreign xml:lang="en">three</foreign></item>
<item><foreign xml:lang="en">four</foreign></item>
</list>
</p>
<p>
<foreign xml:lang="en">one</foreign>
<foreign xml:lang="en">two</foreign>
<foreign xml:lang="en">three</foreign>
<foreign xml:lang="en">four</foreign>
un
deux
trois
quatre
</p>
</test>



-- Upcoming XSLT/XSL-FO hands-on courses: Wellington, NZ 2009-01 World-wide corporate, govt. & user group XML, XSL and UBL training RSS feeds: publicly-available developer resources and training G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995) Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread