the chain of transformations looking like:
Wikidata QID → VIAF ID → LC nID → corresponding LC name
In this example I’d query the nID n81032917 and return ‡a Fields, Gracie, ‡d 1898-1979
As @tfmorris suggests it would be possible to do this via the id.loc.gov service, but possibly you can do it directly from VIAF as well which might save you a step.
So rather than using "https://viaf.org/viaf/"+value+"/justlinks.json"
as I suggest above, instead you could use
"https://viaf.org/viaf/"+value+"/marc21.xml"
Using the Age UK example (VIAF ID = 158063944) this will return some XML starting like:
<mx:record xmlns:v="http://viaf.org/viaf/terms#" xmlns:srw="http://www.loc.gov/zing/srw/"
xmlns:mx="http://www.loc.gov/MARC21/slim">
<mx:leader>00000nz##a22.....n..4500</mx:leader>
<mx:controlfield tag="001">viaf158063944</mx:controlfield>
<mx:controlfield tag="003">OCoLC</mx:controlfield>
<mx:controlfield tag="008">230102n||azznnabbn##########|a#aaa####|#</mx:controlfield>
<mx:datafield tag="024" ind1="7" ind2=" ">
<mx:subfield code="a">http://viaf.org/viaf/158063944</mx:subfield>
<mx:subfield code="2">uri</mx:subfield>
</mx:datafield>
<mx:datafield tag="040" ind1=" " ind2=" ">
<mx:subfield code="a">VIAF</mx:subfield>
<mx:subfield code="c">VIAF</mx:subfield>
</mx:datafield>
<mx:datafield ind1="2" ind2=" " tag="710">
<mx:subfield code="a">Age Concern England</mx:subfield>
<mx:subfield code="0">(ISNI)0000000404235368</mx:subfield>
</mx:datafield>
There will be repeated 710 fields (mx:datafield with tag = 710) in this XML and you can use the GREL parseXml()
to pull out the LC one. You probably already know, but the 710 field is specific for corporate authors/organisations, and if you were to do the same thing for a person (e.g. Gracie Fields) then you'd be looking for a 700 field instead.
There are going to be a variety of ways to extract the data you want from the XML, but a couple of examples might be:
filter(value.parseXml().select("mx|datafield[tag=710]"),x,x.select("mx|subfield[code=0]")[0].ownText().startsWith("(LC"))).join("")
and
forEach(value.parseXml().select("mx|subfield[code=0]"),x,if(x.ownText().startsWith("(LC)"),x.parent(),null)).join("")
The first of these specifically looks for the 710 fields and then filters down to those with "(LC)" in the subfield zero, whereas the second will extract any field with a subfield zero that starts with "(LC)" no matter what the MARC field. There are many variations on this theme for selecting the appropriate fields and @tfmorris's examples contain some alternative select()
statements you could also use as the basis of the xml parsing.
Once you have it down to the relevant fields you can extract the various subfields using parseXml()
select()
and ownText()
appropriately. For example, from the previous step if we get the output:
<mx:datafield ind1="2" ind2=" " tag="710">
<mx:subfield code="a">Age Concern England (Organization)</mx:subfield>
<mx:subfield code="0">(LC)n 79009603</mx:subfield>
</mx:datafield>
then we can extract the subfield a by:
value.parseXml().select("mx|subfield[code=a]")[0].ownText()
Parsing the XML requires some slightly more involved processing than the justlinks.json
but hopefully between the examples given by @tfmorris and the ones I've offered here there is enough to show how it can be done. Please do ask if there's anything more I can clarify.
Owen