Hi, Eric, Here is more of a "push" approach (assuming you are able to use XSLT 2.0+)--which I highly recommend whenever working with XSLT. <?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" exclude-result-prefixes="xs" version="2.0"> <xsl:strip-space elements="*"/> <xsl:output method="text"/> <xsl:template match="/"> <xsl:apply-templates select="session"/> </xsl:template> <xsl:template match="presentation"> <xsl:apply-templates/> </xsl:template> <xsl:template match="person"> <xsl:value-of select="."/> <xsl:text>	</xsl:text> <xsl:sequence select=" string-join( (distinct-values(for $a in following-sibling::affiliation return $a)), '|' ) "/> <xsl:text>	</xsl:text> <xsl:sequence select="../paper"/> <xsl:if test="position() ne last()"> <xsl:text> </xsl:text> </xsl:if> </xsl:template> <xsl:template match="affiliation"/> <xsl:template match="paper"/> </xsl:stylesheet> -- Tim A. Thompson Discovery Metadata Librarian Yale University Library www.linkedin.com/in/timathompson [log in to unmask] On Thu, Nov 16, 2017 at 1:56 PM, Brian Sheppard <[log in to unmask]> wrote: > Yeah, those affiliations really want to be within the person element, but > ... > > This seems to work for me: > > <?xml version="1.0" encoding="utf-8"?> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:func="http://exslt.org/functions" xmlns:date="http://exslt.org/ > dates-and-times" xmlns:exsl="http://exslt.org/common" version="1.0" > exclude-result-prefixes="func exsl date xsl"> > <xsl:output method="xml" omit-xml-declaration="yes" version="1.0" > encoding="utf-8" indent="yes"/> > <!-- <xsl:preserve-space elements="*"/> --> > <xsl:variable name="nl"> > <xsl:value-of select="' '"/> > </xsl:variable> > <xsl:variable name="tab"> > <xsl:value-of select="'	'"/> > </xsl:variable> > <xsl:template match="/"> > <xsl:for-each select="//person"> > <xsl:value-of select="concat(normalize-space(.), $tab )"/> > <xsl:call-template name="get_affil"> > <xsl:with-param name="pers"> > <xsl:value-of select="."/> > </xsl:with-param> > </xsl:call-template> > <xsl:value-of select="concat( $tab, ../paper )"/> > <xsl:value-of select="$nl"/> > </xsl:for-each> > </xsl:template> > <!-- ************************ --> > <xsl:template name="get_affil"> > <xsl:param name="pers"/> > <xsl:for-each select="following-sibling::affiliation[ > preceding-sibling::person[1] = $pers ]"> > <xsl:value-of select="normalize-space(.)"/> > <xsl:if test="position() != last()"> > <xsl:value-of select="'|'"/> > </xsl:if> > </xsl:for-each> > </xsl:template> > </xsl:stylesheet> > > > > > On November 16, at 11:42 AM, Eric Lease Morgan <[log in to unmask]> wrote: > > > > How can I use XSLT to find the direct descendants of a given element > with a given name? > > > > I want to create a tab-delimited version of an XML file. I have the > following XML snippet, and notice how each of the persons in the first > presentation have a single affiliation, but the person of the second > presentation has two affiliations: > > > > <session> > > <presentation> > > <person>RICHARD G. ANDERSON</person> > > <affiliation>Lindenwood University</affiliation> > > <person>AREERAT KICHKHA</person> > > <affiliation>Lindenwood University</affiliation> > > <paper>Is Less More?</paper> > > </presentation> > > <presentation> > > <person>BRIAN W. SLOBODA</person> > > <affiliation>University of Maryland</affiliation> > > <affiliation>University College</affiliation> > > <paper>Inflation Policies</paper> > > </presentation> > > </session> > > > > I want my resulting tab-delimited file to look like this: > > > > RICHARD G. ANDERSON Lindenwood University Is Less > More? > > AREERAT KICHKHA Lindenwood University Is Less > More? > > BRIAN W. SLOBODA University of Maryland|University College > Inflation Policies > > > > I have the following XSLT snippet, but my process of getting > affiliations is not nearly correct: > > > > <xsl:for-each select=".//presentation"> > > <xsl:for-each select=".//person"> > > <xsl:value-of select="normalize-space(.)"/>< > xsl:text>	</xsl:text> > > <xsl:value-of select="normalize-space(../ > affiliation)"/><xsl:text>	</xsl:text> > > <xsl:value-of select="normalize-space(../ > paper)"/><xsl:text> </xsl:text> > > </xsl:for-each> > > </xsl:for-each> > > > > Can you offer any suggestions? What sort of XPath expression should I be > using to find all of the affiliation elements between person elements? > Something with following-sibling? > > ————————————————————————————— > Brian Sheppard > UW Digital Collections Center > [log in to unmask] > > > > > >