0

I'm trying to render the $respStmt entries in this TEI Header:

<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="reeve-prog">
<teiHeader>
    <fileDesc>
        <titleStmt>
            <title type="statusBar">The Progress of Romance</title>
            <author>
                <person xml:id="CR" sex="F" href="http://en.wikipedia.org/wiki/Clara_Reeve">
                    <forename>Clara</forename>
                    <surname>Reeve</surname>
                    <born when="1729">1729</born>
                    <died when="1807-12-03">3 December 1807</died>
                    <occupation>Writer</occupation>
                    <occupation>Novelist</occupation>
                    <trait type="Marital Status">Unmarried</trait>
                    <nationality>English</nationality>
                </person>
            </author>
            <respStmt>
                <resp>Transcription and correction</resp>
                <name>Elizabeth Ricketts</name>
                <name>Tonya Howe</name>
            </respStmt>
            <respStmt>
                <resp>Correction, editorial commentary, and markup</resp>
                <name>Incomplete</name>
            </respStmt>
        </titleStmt>
     </filedesc>
   </teiHeader>
</TEI>

In a list that looks like this:

<li class="list-unstyled">Transcription and correction: Elizabeth Ricketts, Tonya Howe</li>
<li class="list-unstyled">Correctionm editorial commentary, and markup: Incomplete</li>

I have added this code to a larger function, and it works with multiple $name items, but I get a cardinality issue with more than one $resp item:

for $resp in $header
                return
                <li class="list-unstyled">
                    {concat($titleStmt/tei:respStmt/tei:resp, ': ' , string-join($titleStmt/tei:respStmt/tei:name, ', '))                    }
                </li>

I've spelled out the elements in the concat as part of my learning process. Many, many thanks to Martin Honnen and milijan!

Here is the XQL file as a whole--I know it's not pretty: https://gist.github.com/tonyahowe/9ec27e9261116bdb11b0cfc2cecc5ea7

UPDATE: Progress! Now I'm getting a weird kind of repetition, though. With this code:

{
                let $respStmt := $header//tei:respStmt
                for $resps in $respStmt
                return
                <li class="list-unstyled">
                    {concat($resps, ': ' , string-join($names, ', '))                    }
                </li>
            }

I'm getting the following result:

Transcription and correctionElizabeth RickettsTonya Howe: Elizabeth Ricketts, Tonya Howe, Incomplete
Correction, editorial commentary, and markupIncomplete: Elizabeth Ricketts, Tonya Howe, Incomplete

It looks like the $resp cardinality issue has been solved, but now each $name in each $respStmt is being duplicated--the information on the left side of the colon is correct, but on the right side of the colon, all the $names are being reproduced. Arg!

Tonya Howe
  • 57
  • 5
  • 1
    I am not sure what `$n//$respStmt/tei:name` with two variables is supposed to achieve but assuming `$n` is a `respStmt` element having `tei:name` children you can simply use `string-join($n/tei:name, ', ')` where you want your comma separated name list. – Martin Honnen Oct 29 '17 at 16:53
  • Thank you, Martin! I've combined your response with milijan's, below, and it now works partially, but I'm getting a cardinality error with more than one $respStmt in a TEI file. I'll respond more fully in a revised question! – Tonya Howe Nov 07 '17 at 15:04

2 Answers2

0

I am not absolutely sure what is exactly the output you are looking for, but this is how I understand it. Let's say you have an XML document (contributors.xml):

<document>
<respStmt>
  <resp>Transcription, editorial commentary, and markup</resp>
  <name>students of X Y University</name>
  <name>First Specific Contributor</name>
  <name>Second Specific Contributor</name>
  <name>Third Specific Contributor</name>
</respStmt>
<respStmt>
  <resp>Editorial review</resp>
  <name>Reviewer Name</name>
  <name>Reviewer2 Name</name>
</respStmt>
<respStmt>
  <resp>Graphic design</resp>
  <name>Designer Name</name>
</respStmt>
</document>

If you want your output to be like this:

<li class="list-unstyled">Transcription, editorial commentary, and markup: students of X Y University, First Specific Contributor, Second Specific Contributor, Third Specific Contributor</li>
<li class="list-unstyled">Editorial review: Reviewer Name, Reviewer2 Name</li>
<li class="list-unstyled">Graphic design: Designer Name</li>

you can use xquery script like this:

let $document := doc('contributors.xml')/*

for $resp-stmt in $document/respStmt
   return
   <li class="list-unstyled">
   {
       concat($resp-stmt/resp, ': ' , string-join($resp-stmt/name, ', '))

   }
   </li>

The solution is in Martin Honnen's comment on your question.

If you want your output to be like this:

<li class="list-unstyled">Transcription, editorial commentary, and markup: students of X Y University, First Specific Contributor, Second Specific Contributor, and Third Specific Contributor</li>
<li class="list-unstyled">Editorial review: Reviewer Name and Reviewer2 Name</li>
<li class="list-unstyled">Graphic design: Designer Name</li>

you can use this xquery script:

let $document := doc('contributors.xml')/*
for $resp-stmt in $document/respStmt
let $name := $resp-stmt/name
let $name-count := count($name)
   return
   <li class="list-unstyled">
   {concat($resp-stmt/resp, ': ')}
   {
        if ($name-count le 2)
        then string-join($name, ' and ')
        else
            concat(
                string-join($name[position() = (1 to last() - 1)] , ', '),
                ', and ',
                $name[last()])
   }
   </li>

The solution is in the code you have provided.

To make this xquery codes operable, you have to define proper namespaces and use them where appropriate.

UPDATE: Script in this self contained example with contributors.xml as an input file that you provided, should give you what you are trying to achieve:

declare namespace tei = 'http://www.tei-c.org/ns/1.0';    
let $document := doc('contributors.xml')/*

for $resp-stmt in $document//tei:respStmt
return
<li class="list-unstyled">
    {concat($resp-stmt/tei:resp, ': ' , string-join($resp-stmt/tei:name, ', '))}
</li>

In your *.xql file I belive there is an issue because you did not define $resp variable as it should be defined. You are actually saying that $resp is a $header. Try this:

for $resp in $header//tei:respStmt
return
<li class="list-unstyled">
   {concat($header//tei:resp, ': ' , string-join($header//tei:name, ', '))}
</li>

Also, in you XPath expressions you don't have to go through all your nodes to get descendant that you want. Use // axis specifier instead when that path is unambiguous, because querying the eXist-db would be much more efficient that way.

UPDATE 2: In your new update you are using $names variable which is out of context, and that is why you are getting those results. I already have given you the solution in my previous update, but this you can just copy and paste into your tei2html.xql script and it should work:

{
for $respStmt in $header//tei:respStmt
return
<li class="list-unstyled">
{concat($respStmt/tei:resp, ': ' , string-join($respStmt/tei:name, ', '))}
</li>
}
milijan
  • 387
  • 4
  • 12
  • Thank you! These comments are great helps--I am now running into a cardinality issue, though the code works the way I want it to in some instances. I think I'll be able to explain in a fuller edit to my original question. – Tonya Howe Nov 07 '17 at 15:06
  • No problem. I have updated my answer based on your new updated information in the question. – milijan Nov 07 '17 at 23:23
  • Okay, some progress has been made, but now I'm getting repetition. I'll update my question and see if I can express what's happening. Thanks for bearing with! – Tonya Howe Nov 08 '17 at 02:48
0

Success! After a lot of trial and error, this is what I came up with:

{ 
 for $respStmt in $respStmts
 let $resp := $respStmt/tei:resp
 let $name := $respStmt/tei:name
 return
 <li class="list-unstyled">
   {$resp} by {string-join($name, ', ')}
 </li>
}

It returns a list item for each $respStmt containing the $resp and the $names, separated by commas. I feel very accomplished. Thanks, everybody, for your help!

Tonya Howe
  • 57
  • 5