Selecting first descendant of a certain name for each instance of a particular ancestor



I have some complex MS-Office XML that looks like what you see at the link but the full source is much longer with many p:sld and p:notes children of document root. Always appearing in the order p:sld, p:notes, p:sld, p:notes http://ift.tt/ZkPg3v


Thanks to JLRishe, I have some xsl that extracts descendant a:t elements and wraps their contents in various tags based on context.


That XSL is as follows



<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR" xmlns:fo="http://ift.tt/vyPH5E" xmlns:a="http://ift.tt/1dB6t9q" xmlns:r="http://ift.tt/1bA4cfb" xmlns:p="http://ift.tt/1eCLHM2">
<xsl:output method="xml"/>

<xsl:template match="/">
<document>
<xsl:apply-templates select="//a:t"/>
</document>
</xsl:template>

<xsl:template match="a:t">
<xsl:variable name="sldAncestor" select="ancestor::p:sld" />
<xsl:variable name="notesAncestor" select="ancestor::p:notes" />
<xsl:variable name="rAncestorPreLevel"
select="ancestor::a:r/preceding-sibling::*[1]/@lvl" />

<xsl:variable name="wrapperName">
<xsl:choose>

<xsl:when test="$sldAncestor and $rAncestorPreLevel = '1'">
<xsl:text>SlideBullet</xsl:text>
</xsl:when>
<xsl:when test="$sldAncestor and $rAncestorPreLevel = '2'">
<xsl:text>SlideBullet1</xsl:text>
</xsl:when>
<xsl:when test="$sldAncestor and $rAncestorPreLevel = '3'">
<xsl:text>SlideBullet2</xsl:text>
</xsl:when>

<xsl:when test="$notesAncestor and $rAncestorPreLevel = '0'" >
<xsl:text>StudentNotes</xsl:text>
</xsl:when>

<xsl:when test="$notesAncestor and $rAncestorPreLevel = '1'" >
<xsl:text>StudentNotes</xsl:text>
</xsl:when>

<xsl:when test="$notesAncestor and $rAncestorPreLevel = '2'">
<xsl:text>Student_Notes_Bullet</xsl:text>
</xsl:when>
<xsl:when test="$notesAncestor and $rAncestorPreLevel = '3'">
<xsl:text>Student_Notes_Bullet_1</xsl:text>
</xsl:when>

<xsl:otherwise>Body</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:element name="{$wrapperName}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>

</xsl:stylesheet>


But I want to expand that be able to select the first a:t element that appears inside of each p:sld and wrap that in the tags <SlideTitleGhost></SlideTitleGhost>.


Similarly I want to be able to select the first a:t element inside each p.notes element and wrap its contents with the tags <PageBreak /><StudentNotes></StudentNotes>


Note that not all a:t elements are siblings. Sibling a:t elements are children of a:r elements but there are multiple a:r elements descended from each p:notes or p:sld element. And those a:r elements cannot be expected to be siblings either. The last part of the xpath to each a:t element goes //p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t


I'm using Saxon-HE on windows but could switch processors if needed.


The desired output would look like this.



<?xml version="1.0" encoding="UTF-8"?>
<document xmlns:fo="http://ift.tt/vyPH5E" xmlns:a="http://ift.tt/1dB6t9q" xmlns:r="http://ift.tt/1bA4cfb" xmlns:p="http://ift.tt/1eCLHM2">
<SlideTitleGhost>header text</SlideTitleGhost>
<Body>body text </Body>
<Body>body text </Body>
<Body>body text </Body>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet1>bulleted2 text</SlideBullet1>
<SlideBullet1>bulleted2 text</SlideBullet1>
<SlideBullet1>bulleted2 text</SlideBullet1>
<SlideBullet1>bulleted2 text</SlideBullet1>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet>bulleted text</SlideBullet>
<SlideBullet>bulleted text</SlideBullet>
<Body>body text</Body>
<Body>body text</Body>
<Body>footer text</Body>
<Body>10</Body>
<Body>10</Body>
<PageBreak />
<StudentNotes>notes header text</StudentNotes>
<Body>notes body text</Body>
<StudentNotes>notes body text</StudentNotes>
<StudentNotes>notes table header text</StudentNotes>
<StudentNotes>notes table header text</StudentNotes>
<StudentNotes>notes table body text</StudentNotes>
<StudentNotes>table body text</StudentNotes>
<StudentNotes>notes table body text</StudentNotes>
<StudentNotes>notes table body text</StudentNotes>
<StudentNotes>notes table body text</StudentNotes>
<StudentNotes>notes table body text</StudentNotes>
</document>

No comments:

Post a Comment