Print

Print


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>&#09;</xsl:text>
        <xsl:sequence
            select="
                string-join(
                (distinct-values(for $a in following-sibling::affiliation
                return
                    $a)), '|'
                )
                "/>
        <xsl:text>&#09;</xsl:text>
        <xsl:sequence select="../paper"/>
        <xsl:if test="position() ne last()">
            <xsl:text>&#10;</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="'&#10;'"/>
>   </xsl:variable>
>   <xsl:variable name="tab">
>     <xsl:value-of select="'&#9;'"/>
>   </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>&#09;</xsl:text>
> >      <xsl:value-of select="normalize-space(../
> affiliation)"/><xsl:text>&#09;</xsl:text>
> >      <xsl:value-of select="normalize-space(../
> paper)"/><xsl:text>&#10;</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]
>
>
>
>
>
>