Print

Print


Hello Ray,

If one wishes to convert the names of MODS elements with a @type attribute (within a restricted range of @type values) to names where the type value occurs before the name of the element, one can use an XQuery script like that at the bottom of this mail.

<note type="admin">…</note> will then be converted to <adminNote>…</adminNote>, whereas all other elements will stay the same, including e.g. <note type="accrual">…</note>. By editing the list of type values one wishes to transform, one can control which element names are changed (and @type attributes are dropped). Any MODS record can be passed as the $mods variable.

This simple identity transform can be generalized to attributes in general, should one wish to make transformations based on other attributes, and it can equally well be expressed using XSLT.

MODS has to be convertible to RDF format, but I do not see any technical reasons for MODS to leave behind the XML-spirited approach it has followed so far (with the exception of the originInfo dates) for an approach which seeks to mimic RDF. If MARCXML can be converted to BIBFRAME, so can MODS. MODS should instead impose a stricter schema and remove MARC cruft.

Best,

Jens

On Feb 8, 2013, at 5:57 PM, Jens Østergaard Petersen <[log in to unmask]> wrote:

Hello Ray,

I agree that this is one way of converting MODS to RDF. If this is to decide how MODS is elaborated, I see we are in for a proliferation of new elements.

I don't see how concatenating the @type and the local-name of an element, <say <note>, can be at all difficult, for a restricted list of (say, 15) @type values ….

I think MODS should be able to stand on it own. I think there is virtue in simplicity.

Jens

On Feb 8, 2013, at 4:50 PM, Ray Denenberg <[log in to unmask]> wrote:

From: Jens Østergaard Petersen
> In MODS, @type is used to subcategorize. We don't have <personalName> and
> <corporateName> and so on - and lucky for that.
 
I don't agree that we are lucky for that.  MODS name, using a type attribute rather than defining separate element names, reflects design thinking of perhaps 12 years ago. It did not consider (too early to) the implications of trying to represent MODS in RDF.
 
If you were creating RDF properties for these, and you knew up front that there most likely would never be more than a small number of types - personal, conference, corporate, and family, to begin and possibly a small handful added over time - you would create properties personalName, conferenceName, corporateName, and famililyName (all subproperties of property 'name').   I think the same applies to title: uniformTitle, abbreviatedTitle, etc.
 
In fact, for a MODS element where there might be hundreds of types, some well-known and others not - let's say, <note>  - it isn't clear that just defining <note> with @type is necessarily the best approach.   Suppose you decide that 90% of the time you will use 15 note types and the other 10% the type may be arbitrary.  I would define properties for the more popular types, e.g.  actionNote, adminNote, languageNote, etc. whose objects are all string, and one property 'note" where the object is an object property where the type can be explicitly stated.
 
Something to consider for version 4 perhaps.
 
Ray



xquery version "1.0";
 
declare namespace mods="http://www.loc.gov/mods/v3";
declare namespace xlink="http://www.w3.org/1999/xlink";
declare namespace functx = "http://www.functx.com";

declare function functx:capitalize-first($arg as xs:string?) as xs:string? {      
   concat(upper-case(substring($arg,1,1)),
             substring($arg,2))
};

declare function local:type-element-names($input as item()*, $typed-elements) as item()* {
for $node in $input
   return
      typeswitch($node)
        case element()
           return
              element {
              if (local-name($node) = $typed-elements/element/name and $node/@type = $typed-elements/element[name = local-name($node)]/type-value)
              then concat($node/@type, functx:capitalize-first(local-name($node)))
              else name($node)} {
                for $att in $node/@*
                   return
                      if (local-name($node) = $typed-elements/element/name and $node/@type = $typed-elements/element[name = local-name($node)]/type-value)
                      then ()
                      else attribute {name($att)} {$att}
                ,
                for $child in $node
                   return local:type-element-names($child/node(), $typed-elements)
              }
        default return $node
};

let $typed-elements :=
    <typed-elements>
    <element>
        <name>name</name>
        <type-value>personal</type-value>
        <type-value>corporate</type-value>
        <type-value>conference</type-value>
        <type-value>family</type-value>
    </element>
    <element>
        <name>namePart</name>
        <type-value>given</type-value>
        <type-value>family</type-value>
    </element>
    <element>
        <name>note</name>
        <type-value>contents</type-value>
        <type-value>action</type-value>
        <type-value>admin</type-value>
        <type-value>language</type-value>
    </element>
    </typed-elements>

let $mods :=

<mods xmlns="http://www.loc.gov/mods/v3">
    <titleInfo>
        <title>Ethnolinguistic notes on the Dungan</title>
    </titleInfo>
    <name type="personal">
        <namePart type="given">Lisa E.</namePart>
        <namePart type="family">Husmann</namePart>
        <role>
            <roleTerm type="code" authority="marcrelator">aut</roleTerm>
        </role>
    </name>
    <note type="contents">contents</note>
    <note type="accrual">accrual</note>
    <note type="admin">admin</note>
    <note type="revision">revision</note>
</mods>

return
    local:type-element-names($mods, $typed-elements)