/research/projects/schematrans/seel/tutorial/section2.htm

originally: http://www.oclc.org/research/projects/schematrans/seel/tutorial/section2.htm

Section 2: Contexts

The translation of metadata standards would be easy, possibly even trivial, if the process involved nothing more than a series of unconditional statements expressing an equivalence between a and b, MARC <650><a> and Dublin Core <subject>, and so on. But translations involving real standards are usually contingent on some property in a source or target record, as we have already seen in the examples in Section 1. Here we describe the technical details of the <context> element, which is used to express these concepts.

Starting with the examples in this section, we'll develop a fairly substantial translation from ONIX to MARC, using the Library of Congress crosswalk and the Record Builder document as references. To keep things focused, we'll work on this Morfrom record, which was generated from this native XML record by a Morfrom reader tuned to ONIX. In Section 5, we'll collect the maps into a comprehensive translation.

For those readers who are unfamiliar with the details of ONIX, we need to point out that ONIX has two tagsets: one with terse element names and another with human-readable names. Since the terse names are used for machine processing, we refer to them in the Seel maps. But since they are difficult to read, our discussion always highlights the equivalent descriptive tag in green.

One more point about the examples. For the sake of simplicity, we will assume that the records being discussed will eventually be rendered by a Morfrom writer into some sort of XML syntax. For example, we will refer to a MARC field with the notation <245><a> instead of a circumlocution or the Morfrom equivalent <field name="245"><field name="a">. Occasionally, as it aids understanding, we will show the Morfrom version, set apart from the text when there are large sections.

Let's begin the discussion of contexts in the ONIX-MARC crosswalk with a simple example. Map 2.1 shows how a MARC topical subject field is built from an ONIX <subject> element. More literally, Map 2.1 says that the data located at <subject><b070>SubjectHeadingText is transferred to <650><a>Topical Term in a certain circumstance: when the value at <b067> SubjectSchemeIdentifier equals 04 (an ONIX code indicating the Library of Congress Subject Headings). The <equals> statement in the <context> block spells out the details.

Map 2.1 N.B.

<map id="map:13">
  <source>
    <mainpath>
      <step name="subject"/>
      <path><step name="b070"/></path>
    </mainpath>
    <context>
      <equals>
        <path><step name="b067"/></path>
        <value>04</value>
      </equals>
    </context>
  </source>
  <target>
    <mainpath>
      <step name="650"/>
      <path><step name="a"/></path>
    </mainpath>
  </target>
</map>

Map 2.1 translates the relevant portion of our ONIX record to the Morfrom fragment shown below. From this, the MARC syntax 650 $a juvenile fiction can be generated using a Morfrom writer tuned to MARC's display syntax.

<field name="650">
  <field name="a"><value>juvenile fiction</value></field>
</field>

Now let's consider a slightly more complex example. We'll start with the outcome and work backwards through the Seel code that produces it. Map 2.2 translates the ONIX <contributor> element to a MARC 100 Personal Name statement. When Map 2.2 is applied to our ONIX record, the Morfrom code shown here is generated, from which the MARC field 100 #1 $a Vera Rosenberry $c Ph.D. $e author can be rendered as a display format by a Morfrom writer.

Map 2.2

<map id="map:00">
  <source>
    <mainpath>
      <step name="contributor" position="1"/>
      <path pid="1"><step name="b037"/></path>
      <path pid="2"><step name="b043"/></path>
      <path pid="3"><step name="b035"/></path>
      <path pid="4"><step name="b035"/></path>
    </mainpath>
    <context pid="3">
      <equals>
        <transfer/>
        <value>A01</value>
      </equals>
    </context>
    <context pid="4">
      <equals>
        <transfer/>
        <value>A12</value>
      </equals>
    </context>
  </source>
  <target>
    <mainpath>
      <step name="100"/>
      <path pid="1"><step name="a"/></path>
      <path pid="2"><step name="c"/></path>
      <path pid="3"><step name="e"/></path>
      <path pid="4"><step name="e"/></path>
    </mainpath>
    <context pid="1">
      <equals>
        <path place="before"><step name="i1"/></path>
        <value>1</value>
      </equals>
      <equals>
        <path place="before"><step name="i2"/></path>
        <value>#</value>
      </equals>
    </context>
    <context pid="3">
      <equals>
        <transfer/>
        <value>author</value>
      </equals>
    </context>
    <context pid="4">
      <equals>
        <transfer/>
        <value>illustrator</value>
      </equals>
    </context>
  </target>
</map>

Map 2.2 shows <context> elements in the <source> as well as the <target>. The <context> elements have some of the effect of an if-then statement in a procedural language like Java, which might be read like this: If the value of ONIX <contributor><b035> ContributorRole is A01, then the value of MARC <100><e> is author. If the ContributorRole equals A12, then <100><e> is illustrator</e></100>. Otherwise, the path isn't translated.

But in a declarative language like Seel, it's more accurate to say that the <context> elements describe the conditions in which a <path> statement specified in the <mainpath> element is realized, or is "true." Either the source or the target may describe a context, or the context may be omitted altogether. For example, the translation of the <contributor><b037> PersonNameInverted element to MARC <100><a> constructs a context, so it is described in the target but not the source. The <100><a> element requires the generation of indicator elements, as did the <245><a> element we discussed in Map 1.1 in Section 1. If the map between two paths is not dependent on any particular circumstance, the <context> element is omitted and the Morfrom <value> data is simply transferred between the aligned paths. For example, the ONIX <contributor><b043> TitleAfterNames element always translates to <100><c>. So no context statement is required.

Because Map 2.2 translates an ONIX subtree into a MARC subtree, it has to keep track of lots of branches and associate them with appropriate contexts. That's the purpose of the "pid" (or path id) attribute on the <path> and <context> statements. The pid does three things in a Seel map. First, it associates paths across the <source> and <target> blocks within a map. This is the means by which subtrees are aligned. Second, it links a path to a context within the same <source> or <target> block. For example, "pid=3" is associated with the ONIX context in which <contributor><b035> ContributorRole equals A01. Third, it associates a reference field with a micro section. Micro sections will be addressed in a later section.

Notice that the number of source paths equals the number of target paths. In Map 2.2, there are four. This is as it should be, because a map is a binary relationship that associates a source with a target and vice versa. If the number of paths in the source and target were unequal, it would be like saying (blank) = a or b = (blank). These are one-sided relationships, and the Seel interpreter would generate an error message.

If the map involves more than one path, each path must be indexed with the pid attribute, as shown in Map 2.2. But since contexts are optional, it isn't necessary to define a context for every path. In the <source> block in Map 2.2, contexts are described only for paths 3 and 4. In the <target> block, contexts are defined only for paths 1, 3, and 4. The map for path 2 doesn't require a context, so none is defined in either the source or the target.

Contrast this example with Map 2.1 in this section or Map 1.1 in Section 1. In these examples, only one path is defined in the map. No pid attributes are necessary because the source-target map as well as the associations between paths and contexts are unambiguous.

Map 2.3 illustrates another type of <context> statement. In this map, a MARC 245 Title field is built from the ONIX <b028> DistinctiveTitle element. The values for the indicators are dependent on the existence of the <contributor><b037> PersonNameInverted element. If this path exists, the MARC indicator values are 10; otherwise, they are 00. The <exists> element simply checks for the presence of a path without having to check the value of the data at that location (as the <equals> statements do in Maps 2.1 and 2.2). And as Map 2.3 shows, the <exists> element can also be negated.

Map 2.3

<map id="map:04">
  <source>
    <mainpath>
      <path pid="1"><step name="b028"/></path>
      <path pid="2"><step name="b028"/></path>
      <path pid="3"><step name="b029"/></path>
    </mainpath>
    <context pid="1">
      <exists>
        <path><step name="contributor"/><step name="b037"/></path>
      </exists>
    </context>
    <context pid="2">
      <exists negate="true">
        <path><step name="contributor"/><step name="b037"/></path>
      </exists>
    </context>
  </source>
  <target>
    <mainpath>
      <step name="245"/>
      <path pid="1"><step name="a"/></path>
      <path pid="2"><step name="a"/></path>
      <path pid="3"><step name="b"/></path>
    </mainpath>
    <context pid="1">
      <equals>
        <path place="before"><step name="i1"/></path>
        <value>1</value>
      </equals>
      <equals>
        <path place="before"><step name="i2"/></path>
        <value>0</value>
      </equals>
    </context>
    <context pid="2">
      <equals>
        <path place="before"><step name="i1"/></path>
        <value>0</value>
      </equals>
      <equals>
        <path place="before"><step name="i2"/></path>
        <value>0</value>
      </equals>
    </context>
  </target>
</map>

When Map 2.3 is applied to our sample ONIX record, it produces the MARC record shown here.

Summary

To summarize, we have shown how Seel maps can be conditionally executed. First, a pair of paths or subtrees are aligned using the <mainpath> element of the <source> and the <target>. A set of conditions are then be specified using the <exists> and <equals> statements in the <context> element. The "pid" attribute keeps the references straight.

The <mainpath> and <context> elements permit the expression of sophisticated relationships in Seel, while retaining the essential metaphor of the binary and symmetric map expressed in a crosswalk. We have illustrated several typical contexts. Consult the Seel DTD for a full specification of the Seel grammar.

In this discussion, we've talked a little too loosely about how Seel handles paths. There's more to be said about this important subject.