add stable field order in record building, use delegate map in MarcRecord, more filters for field processing in MarcRecord

This commit is contained in:
Jörg Prante 2022-10-21 17:07:08 +02:00
parent 9b1bac1e6f
commit 0945112bc0
21 changed files with 249 additions and 89 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib
name = marc
version = 2.8.0
version = 2.9.0
org.gradle.warning.mode = ALL

View file

@ -15,13 +15,10 @@
*/
package org.xbib.marc;
/**
*
*/
public class LightweightMarcRecordAdapter extends MarcRecordAdapter {
public LightweightMarcRecordAdapter(MarcRecordListener marcRecordListener) {
super(marcRecordListener);
super(marcRecordListener, false);
this.builder = Marc.builder().lightweightRecord();
}

View file

@ -662,7 +662,9 @@ public final class Marc {
private MarcGenerator marcGenerator;
private boolean islightweightRecord;
private boolean isLightweightRecord;
private boolean isStableFieldOrder;
private Pattern keyPattern;
@ -1116,8 +1118,8 @@ public final class Marc {
}
public Marc.Builder addField(MarcField marcField) {
boolean keymatch = keyPattern == null || marcField.matchKey(keyPattern) != null;
boolean valuematch = valuePattern == null || marcField.matchValue(valuePattern) != null;
boolean keymatch = keyPattern == null || marcField.matchesKey(keyPattern);
boolean valuematch = valuePattern == null || marcField.matchesValue(valuePattern);
if (keymatch && valuematch) {
this.marcFieldList.add(marcField);
}
@ -1125,7 +1127,12 @@ public final class Marc {
}
public Marc.Builder lightweightRecord() {
this.islightweightRecord = true;
this.isLightweightRecord = true;
return this;
}
public Marc.Builder stableFieldOrder() {
this.isStableFieldOrder = true;
return this;
}
@ -1134,7 +1141,7 @@ public final class Marc {
* @return MARC record
*/
public MarcRecord buildRecord() {
return new MarcRecord(format, type, recordLabel, marcFieldList, islightweightRecord);
return new MarcRecord(format, type, recordLabel, marcFieldList, isLightweightRecord, isStableFieldOrder);
}
/**

View file

@ -199,8 +199,8 @@ public class MarcField implements Comparable<MarcField> {
* @param pattern the pattern
* @return this MARC field if pattern macthes, otherwise null
*/
public MarcField matchKey(Pattern pattern) {
return pattern.matcher(toTagIndicatorKey()).matches() ? this : null;
public boolean matchesKey(Pattern pattern) {
return pattern.matcher(toTagIndicatorKey()).matches();
}
/**
@ -208,16 +208,16 @@ public class MarcField implements Comparable<MarcField> {
* @param pattern the pattern to match
* @return thhis MARC field if pattern matches, or null if not
*/
public MarcField matchValue(Pattern pattern) {
public boolean matchesValue(Pattern pattern) {
if (builder.value != null && pattern.matcher(builder.value).matches()) {
return this;
return true;
}
for (Subfield subfield : builder.subfields) {
if (pattern.matcher(subfield.getValue()).matches()) {
return this;
return true;
}
}
return null;
return false;
}
/**

View file

@ -0,0 +1,8 @@
package org.xbib.marc;
@FunctionalInterface
public interface MarcFieldHandler {
void field(MarcField marcField);
}

View file

@ -26,19 +26,21 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* A MARC record. This is an extended MARC record augmented with MarcXchange information.
*/
@SuppressWarnings("serial")
public class MarcRecord extends LinkedHashMap<String, Object> {
public class MarcRecord implements Map<String, Object> {
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
private final Map<String, Object> delegate;
private String format;
private String type;
@ -47,8 +49,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
private final transient List<MarcField> marcFields;
private MarcRecord(Map<String, Object> map) {
super(map);
private MarcRecord(Map<String, Object> delegate) {
this.delegate = delegate;
this.marcFields = new LinkedList<>();
}
@ -65,8 +67,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
String type,
RecordLabel recordLabel,
List<MarcField> marcFields,
boolean lightweight) {
super();
boolean lightweight,
boolean stable) {
this.format = format;
this.type = type;
this.recordLabel = recordLabel;
@ -74,9 +76,7 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
throw new NullPointerException("record label must not be null");
}
this.marcFields = marcFields;
if (!lightweight) {
createMap();
}
this.delegate = lightweight ? Map.of() : createMap(stable);
}
/**
@ -97,9 +97,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
String leaderTag,
RecordLabel recordLabel) {
MarcRecord marcRecord = new MarcRecord(map);
marcRecord.parseMap(map, ".", "", (key, value) -> {
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build());
});
marcRecord.parseMap(map, ".", "", (key, value) ->
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build()));
if (map.containsKey(formatTag)) {
marcRecord.format = map.get(formatTag).toString();
}
@ -151,38 +150,134 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
}
/**
* Return the MARC fields of this record with a given tag.
* Filter the MARC fields of this record with a given tag.
*
* @param tag the MARC tag
* @return the MARC field list matching the given tag.
*/
public List<MarcField> getFields(String tag) {
return marcFields.stream().filter(marcField -> marcField.getTag().equals(tag))
.collect(Collectors.toList());
public void filter(String tag, MarcFieldHandler handler) {
filter(marcField -> marcField.getTag().equals(tag), handler);
}
/**
* Return a list of MARC fields of this record where key pattern matches were found.
*
* @param pattern the pattern
* @return a list of MARC fields
*/
public List<MarcField> filterKey(Pattern pattern) {
return marcFields.stream()
.map(field -> field.matchKey(pattern))
.filter(Objects::nonNull)
.collect(Collectors.toList());
public void filter(String tag, String indicator, MarcFieldHandler handler) {
filter(marcField -> marcField.getTag().equals(tag) && marcField.getIndicator().equals(indicator), handler);
}
/**
* Return a list of MARC fields of this record where pattern matches were found.
*
* @param pattern the pattern
* @return a list of MARC fields
*/
public List<MarcField> filterValue(Pattern pattern) {
return marcFields.stream().map(field ->
field.matchValue(pattern)).filter(Objects::nonNull).collect(Collectors.toList());
public void filter(String tag, String indicator, String subfieldId, MarcFieldHandler handler) {
filter(marcField -> marcField.getTag().equals(tag) &&
marcField.getIndicator().equals(indicator) &&
marcField.getSubfieldIds().contains(subfieldId), handler);
}
public void filter(Pattern pattern, MarcFieldHandler handler) {
filter(field -> field.matchesKey(pattern), handler);
}
public void filter(Predicate<? super MarcField> predicate, MarcFieldHandler handler) {
marcFields.stream().filter(predicate).forEach(handler::field);
}
public void filterFirst(Predicate<? super MarcField> predicate, MarcFieldHandler handler) {
marcFields.stream().filter(predicate).findFirst().ifPresent(handler::field);
}
public MarcField getFirst(String tag) {
return getFirst(marcField -> marcField.getTag().equals(tag));
}
public MarcField getFirst(String tag, String indicator) {
return getFirst(marcField -> marcField.getTag().equals(tag) && marcField.getIndicator().equals(indicator));
}
public MarcField getFirst(String tag, String indicator, String subfieldId) {
return getFirst(marcField -> marcField.getTag().equals(tag) &&
marcField.getIndicator().equals(indicator) &&
marcField.getSubfieldIds().contains(subfieldId));
}
public MarcField getFirst(Predicate<? super MarcField> predicate) {
final MarcField[] array = new MarcField[1];
filterFirst(predicate, marcField -> array[0] = marcField);
return array[0];
}
public List<MarcField> getAll(String tag) {
return getAll(marcField -> marcField.getTag().equals(tag));
}
public List<MarcField> getAll(String tag, String indicator) {
return getAll(marcField -> marcField.getTag().equals(tag) && marcField.getIndicator().equals(indicator));
}
public List<MarcField> getAll(String tag, String indicator, String subfieldId) {
return getAll(marcField -> marcField.getTag().equals(tag) &&
marcField.getIndicator().equals(indicator) &&
marcField.getSubfieldIds().contains(subfieldId));
}
public List<MarcField> getAll(Predicate<? super MarcField> predicate) {
List<MarcField> list = new LinkedList<>();
filter(predicate, list::add);
return list;
}
@Override
public int size() {
return delegate.size();
}
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
@Override
public Object get(Object key) {
return delegate.get(key);
}
@Override
public Object put(String key, Object value) {
return delegate.put(key, value);
}
@Override
public Object remove(Object key) {
return delegate.remove(key);
}
@Override
public void putAll(Map<? extends String, ?> m) {
delegate.putAll(m);
}
@Override
public void clear() {
delegate.clear();
}
@Override
public Set<String> keySet() {
return delegate.keySet();
}
@Override
public Collection<Object> values() {
return delegate.values();
}
@Override
public Set<Entry<String, Object>> entrySet() {
return delegate.entrySet();
}
@Override
@ -197,21 +292,26 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
return (recordLabel.toString() + marcFields.toString()).hashCode();
}
public String toString() {
return delegate.toString();
}
@SuppressWarnings("unchecked")
private void createMap() {
put(FORMAT_TAG, format);
put(TYPE_TAG, type);
put(LEADER_TAG, recordLabel.toString());
private Map<String, Object> createMap(boolean stable) {
Map<String, Object> map = stable ? new TreeMap<>() : new LinkedHashMap<>();
map.put(FORMAT_TAG, format);
map.put(TYPE_TAG, type);
map.put(LEADER_TAG, recordLabel.toString());
for (MarcField marcField : marcFields) {
String tag = marcField.getTag();
int repeat;
Map<String, Object> repeatMap;
if (!containsKey(tag)) {
if (!map.containsKey(tag)) {
repeatMap = new LinkedHashMap<>();
repeat = 1;
put(tag, repeatMap);
map.put(tag, repeatMap);
} else {
repeatMap = (Map<String, Object>) get(tag);
repeatMap = (Map<String, Object>) map.get(tag);
repeat = repeatMap.size() + 1;
}
String indicator = marcField.getIndicator();
@ -246,6 +346,7 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
repeatMap.put(Integer.toString(repeat), marcField.getValue());
}
}
return map;
}
@SuppressWarnings("unchecked")

View file

@ -28,9 +28,15 @@ public class MarcRecordAdapter implements MarcListener {
protected Marc.Builder builder;
public MarcRecordAdapter(MarcRecordListener marcRecordListener) {
private boolean isStableFieldOrder;
public MarcRecordAdapter(MarcRecordListener marcRecordListener, boolean isStableFieldOrder) {
this.marcRecordListener = marcRecordListener;
this.builder = Marc.builder();
this.isStableFieldOrder = isStableFieldOrder;
if (isStableFieldOrder) {
this.builder.stableFieldOrder();
}
}
@Override
@ -58,6 +64,9 @@ public class MarcRecordAdapter implements MarcListener {
public void endRecord() {
marcRecordListener.record(builder.buildRecord());
builder = Marc.builder();
if (isStableFieldOrder) {
builder.stableFieldOrder();
}
}
@Override

View file

@ -0,0 +1,7 @@
package org.xbib.marc;
@FunctionalInterface
public interface MarcRecordHandler {
void record(MarcRecord marcRecord);
}

View file

@ -16,7 +16,7 @@
package org.xbib.marc;
/**
* Interface for catching MARC records.
* Interface for handling MARC records in collections.
*/
public interface MarcRecordListener {

View file

@ -126,7 +126,7 @@ public class MabXMLContentHandler extends MarcContentHandler implements MabXMLCo
}
case FELD: {
String s = content.toString();
MarcField marcField = stack.pop().value(trim ? s.trim() : s).build();
MarcField marcField = stack.pop().value(isTrim ? s.trim() : s).build();
if (marcValueTransformers != null) {
marcField = marcValueTransformers.transformValue(marcField);
}
@ -135,7 +135,7 @@ public class MabXMLContentHandler extends MarcContentHandler implements MabXMLCo
}
case UF: {
String s = content.toString();
stack.peek().subfieldValue(trim ? s.trim() : s);
stack.peek().subfieldValue(isTrim ? s.trim() : s);
break;
}
default:

View file

@ -51,6 +51,7 @@ public enum TypeOfControl {
switch (ch) {
case ' ':
case '#':
case '0':
return UNSPECIFIED;
case 'a':
return ARCHIVAL;

View file

@ -75,7 +75,7 @@ public class MarcContentHandler
protected MarcValueTransformers marcValueTransformers;
protected boolean trim;
protected boolean isTrim;
private MarcFieldTransformers marcFieldTransformers;
@ -85,6 +85,8 @@ public class MarcContentHandler
private final Set<String> validNamespaces;
private boolean isStableFieldOrder;
public MarcContentHandler() {
this.recordCounter = new AtomicInteger();
this.stack = new LinkedList<>();
@ -160,7 +162,12 @@ public class MarcContentHandler
}
public MarcContentHandler setTrim(boolean trim) {
this.trim = trim;
this.isTrim = trim;
return this;
}
public MarcContentHandler setStableFieldOrder(boolean stableFieldOrder) {
this.isStableFieldOrder = stableFieldOrder;
return this;
}
@ -247,7 +254,7 @@ public class MarcContentHandler
} else {
MarcRecord marcRecord = new MarcRecord(getFormat(), getType(),
RecordLabel.builder().from(label).build(),
marcFieldList, false);
marcFieldList, false, isStableFieldOrder);
marcRecordListener.record(marcRecord);
}
}
@ -405,7 +412,7 @@ public class MarcContentHandler
}
case SUBFIELD: {
String s = content.toString();
stack.peek().subfieldValue(trim ? s.trim() : s);
stack.peek().subfieldValue(isTrim ? s.trim() : s);
break;
}
default: {

View file

@ -21,6 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import org.junit.jupiter.api.Test;
import org.xbib.content.XContentBuilder;
import org.xbib.content.json.JsonXContent;
import org.xbib.marc.label.RecordLabel;
import org.xbib.marc.transformer.value.MarcValueTransformers;
import org.xbib.marc.xml.MarcXchangeWriter;
@ -29,7 +31,10 @@ import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
@ -97,7 +102,10 @@ public class MarcRecordTest {
// only single record
for (MarcRecord marcRecord : builder.iterable()) {
// single 245 field
assertEquals(1, marcRecord.filterKey(Pattern.compile("^245.*")).size());
List<MarcField> list = new ArrayList<>();
Pattern pattern = Pattern.compile("^245.*");
marcRecord.filter(field -> pattern.matcher(field.getTag()).matches(), list::add);
assertEquals(1, list.size());
}
}
}
@ -117,19 +125,6 @@ public class MarcRecordTest {
}
}
@Test
public void testFilterValueIterable() throws Exception {
String s = "summerland.mrc";
try (InputStream in = getClass().getResource(s).openStream()) {
Marc.Builder builder = Marc.builder()
.setInputStream(in)
.setCharset(Charset.forName("ANSEL"));
for (MarcRecord marcRecord : builder.iterable()) {
assertEquals(2, marcRecord.filterValue(Pattern.compile(".*?Chabon.*")).size());
}
}
}
@Test
public void testFilterValue() throws Exception {
String s = "summerland.mrc";
@ -220,4 +215,24 @@ public class MarcRecordTest {
assertEquals("123", marcRecord.getFields().stream().filter(m -> m.getTag().equals("001")).findFirst().get().getValue());
assertEquals("Hello World", marcRecord.getFields().stream().filter(m -> m.getTag().equals("100")).findFirst().get().getFirstSubfieldValue("a"));
}
@Test
public void testMarcRecordFromMapAsMap() throws IOException {
Map<String, Object> map = new TreeMap<>(Map.of("001", "123",
"100", Map.of("_", Map.of("a", "Hello World"))));
MarcRecord marcRecord = MarcRecord.from(map);
assertEquals("{001=123, 100={_={a=Hello World}}}", marcRecord.toString());
XContentBuilder builder = JsonXContent.contentBuilder();
builder.map(marcRecord);
assertEquals("{\"001\":\"123\",\"100\":{\"_\":{\"a\":\"Hello World\"}}}", builder.string());
}
@Test
public void testMarcRecordFilter() {
Map<String, Object> map = Map.of("001", "123",
"100", Map.of("_", Map.of("a", "Hello World")));
MarcRecord marcRecord = MarcRecord.from(map);
marcRecord.filter("001", field -> assertEquals("123", field.getValue()));
marcRecord.filter("100", field -> assertEquals("Hello World", field.getFirstSubfieldValue("a")));
}
}

View file

@ -56,6 +56,7 @@ public class MarcJsonWriterTest {
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
) {
Marc.builder()
.stableFieldOrder()
.setInputStream(inputStream)
.setCharset(Charset.forName("ANSEL"))
.setMarcListener(writer)
@ -78,10 +79,11 @@ public class MarcJsonWriterTest {
"chabon.mrc",
"chabon-loc.mrc"
}) {
StreamMatcher.fileMatch(getClass(), s, ".json", (inputStream, outputStream) -> {
StreamMatcher.fileMatch(getClass(), s, ".record.json", (inputStream, outputStream) -> {
try (MarcJsonWriter writer = new MarcJsonWriter(outputStream)
) {
Marc.builder()
.stableFieldOrder()
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
.setInputStream(inputStream)
@ -107,14 +109,14 @@ public class MarcJsonWriterTest {
"chabon.mrc",
"chabon-loc.mrc"
}) {
StreamMatcher.fileMatch(getClass(), s, ".json", (inputStream, outputStream) -> {
StreamMatcher.fileMatch(getClass(), s, ".record.adapter.json", (inputStream, outputStream) -> {
try (MarcJsonWriter writer = new MarcJsonWriter(outputStream)) {
Marc.builder()
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
.setInputStream(inputStream)
.setCharset(Charset.forName("ANSEL"))
.setMarcListener(new MarcRecordAdapter(writer))
.setMarcListener(new MarcRecordAdapter(writer, true))
.build()
.writeCollection();
}
@ -134,7 +136,7 @@ public class MarcJsonWriterTest {
contentHandler.addNamespace("http://www.ddb.de/professionell/mabxml/mabxml-1.xsd");
contentHandler.setFormat("MARC21");
contentHandler.setType("Bibliographic");
contentHandler.setMarcListener(new MarcRecordAdapter(writer));
contentHandler.setMarcListener(new MarcRecordAdapter(writer, true));
Marc.builder()
.setInputStream(inputStream)
.setContentHandler(contentHandler)

View file

@ -1 +1 @@
{"_FORMAT":"MARC21","_TYPE":"Bibliographic","_LEADER":"00000 M2.01200024 000h","LDR":["------M2.01200024------h"],"FMT":["MH"],"001":[{" 1":[{"a":"HT016424175"}]}],"002":[{"a1":[{"a":"20100705"}]}],"026":[{" 1":[{"a":"HBZHT016424175"}]}],"030":["a|1uc||||||1|"],"036":[{"a1":[{"a":"DE"}]}],"037":[{"b1":[{"a":"lat"}]}],"050":["a|||||||||||||"],"051":["am||||||"],"070":[{" 1":[{"a":"575"}]}],"080":[{" 1":[{"a":"60"}]}],"100":[{" 1":[{"p":"Hildegardis"},{"c":"Bingensis"},{"d":"1098-1179"},{"9":"(DE-588)118550993"}]}],"101":[{" 1":[{"p":"Hildegard"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Heilige, 1098-1179"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Sankt"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Sancta"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abbatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarde"},{"c":"Sainte"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Monte Sancti Ruperti"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"die Heilige"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardt"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Hildegard <<von>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"of Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Sancta Abatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"Santa"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"Sant'"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abbess"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Heilige"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarde"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"di Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarda"},{"c":"di Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarda"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Bingeniläinen"},{"d":"1098-1179"}]},{" 1":[{"p":"Childegard"},{"c":"ot Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Childegard <<ot>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Hildegarde <<de>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"von Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis von Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Sainte"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Alemannia"},{"d":"1098-1179"}]}],"104":[{"b1":[{"p":"Escot, Pozzi"},{"d":"1933-"},{"b":"[Bearb.]"},{"9":"(DE-588)128917687"}]}],"105":[{" 1":[{"p":"Pozzi Escot, Olga"},{"d":"1933-"}]}],"304":[{"b1":[{"a":"Unde quocumque"}]}],"331":[{" 1":[{"a":"Unde quocumque"}]}],"334":[{" 1":[{"a":"Musikdruck"}]}],"359":[{" 1":[{"a":"Hildegard von Bingen"}]}],"425":[{" 1":[{"a":"c 1994"}]},{"a1":[{"a":"1994"}]}],"503":[{"a1":[{"a":"Transkription der mittelalterlichen Neumen in moderne Notation"}]}],"516":[{" 1":[{"a":"Melodien mit unterlegtem Text"}]}],"590":[{" 1":[{"a":"<<The>> Ursula Antiphons ... [Musikdruck]"}]}],"591":[{" 1":[{"a":"Hildegard von Bingen"}]}],"594":[{" 1":[{"a":"[Kassel]"}]}],"595":[{" 1":[{"a":"1994"}]}],"599":[{" 1":[{"a":"HT016424145"}]}],"SYS":["018117852"]}
{"001":[{" 1":[{"a":"HT016424175"}]}],"002":[{"a1":[{"a":"20100705"}]}],"026":[{" 1":[{"a":"HBZHT016424175"}]}],"030":["a|1uc||||||1|"],"036":[{"a1":[{"a":"DE"}]}],"037":[{"b1":[{"a":"lat"}]}],"050":["a|||||||||||||"],"051":["am||||||"],"070":[{" 1":[{"a":"575"}]}],"080":[{" 1":[{"a":"60"}]}],"100":[{" 1":[{"p":"Hildegardis"},{"c":"Bingensis"},{"d":"1098-1179"},{"9":"(DE-588)118550993"}]}],"101":[{" 1":[{"p":"Hildegard"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Heilige, 1098-1179"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Sankt"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Sancta"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abbatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarde"},{"c":"Sainte"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Monte Sancti Ruperti"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"die Heilige"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardt"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Hildegard <<von>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"of Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Sancta Abatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"Santa"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"Sant'"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abbess"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Heilige"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarde"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Ildegarda"},{"c":"di Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"Abatissa"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarda"},{"c":"di Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegarda"},{"c":"de Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Bingeniläinen"},{"d":"1098-1179"}]},{" 1":[{"p":"Childegard"},{"c":"ot Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Childegard <<ot>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Bingen, Hildegarde <<de>>"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"von Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis von Bingen"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegard"},{"c":"Sainte"},{"d":"1098-1179"}]},{" 1":[{"p":"Hildegardis"},{"c":"de Alemannia"},{"d":"1098-1179"}]}],"104":[{"b1":[{"p":"Escot, Pozzi"},{"d":"1933-"},{"b":"[Bearb.]"},{"9":"(DE-588)128917687"}]}],"105":[{" 1":[{"p":"Pozzi Escot, Olga"},{"d":"1933-"}]}],"304":[{"b1":[{"a":"Unde quocumque"}]}],"331":[{" 1":[{"a":"Unde quocumque"}]}],"334":[{" 1":[{"a":"Musikdruck"}]}],"359":[{" 1":[{"a":"Hildegard von Bingen"}]}],"425":[{" 1":[{"a":"c 1994"}]},{"a1":[{"a":"1994"}]}],"503":[{"a1":[{"a":"Transkription der mittelalterlichen Neumen in moderne Notation"}]}],"516":[{" 1":[{"a":"Melodien mit unterlegtem Text"}]}],"590":[{" 1":[{"a":"<<The>> Ursula Antiphons ... [Musikdruck]"}]}],"591":[{" 1":[{"a":"Hildegard von Bingen"}]}],"594":[{" 1":[{"a":"[Kassel]"}]}],"595":[{" 1":[{"a":"1994"}]}],"599":[{" 1":[{"a":"HT016424145"}]}],"FMT":["MH"],"LDR":["------M2.01200024------h"],"SYS":["018117852"],"_FORMAT":"MARC21","_LEADER":"00000 M2.01200024 000h","_TYPE":"Bibliographic"}

View file

@ -0,0 +1 @@
[{"001":["11939876"],"005":["20041229190604.0"],"008":["000313s2000 nyu 000 1 eng "],"010":[{" ":[{"a":" 00029063 "}]}],"020":[{" ":[{"a":"0679450041 (acid-free paper)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"043":[{" ":[{"a":"n-us-ny"}]}],"050":[{"00":[{"a":"PS3553.H15"},{"b":"A82 2000"}]}],"082":[{"00":[{"a":"813/.54"},{"2":"21"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"14":[{"a":"The amazing adventures of Kavalier and Clay :"},{"b":"a novel /"},{"c":"Michael Chabon."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Random House,"},{"c":"c2000."}]}],"300":[{" ":[{"a":"639 p. ;"},{"c":"25 cm."}]}],"650":[{" 0":[{"a":"Comic books, strips, etc."},{"x":"Authorship"},{"v":"Fiction."}]},{" 0":[{"a":"Heroes in mass media"},{"v":"Fiction."}]},{" 0":[{"a":"Czech Americans"},{"v":"Fiction."}]},{" 0":[{"a":"Young men"},{"v":"Fiction."}]},{" 0":[{"a":"Cartoonists"},{"v":"Fiction."}]}],"651":[{" 0":[{"a":"New York (N.Y.)"},{"v":"Fiction."}]}],"655":[{" 7":[{"a":"Humorous stories."},{"2":"gsafd"}]},{" 7":[{"a":"Bildungsromane."},{"2":"gsafd"}]}],"856":[{"42":[{"3":"Contributor biographical information"},{"u":"http://www.loc.gov/catdir/bios/random052/00029063.html"}]},{"41":[{"3":"Sample text"},{"u":"http://www.loc.gov/catdir/samples/random044/00029063.html"}]},{"42":[{"3":"Publisher description"},{"u":"http://www.loc.gov/catdir/description/random0411/00029063.html"}]}],"906":[{" ":[{"a":"7"},{"b":"cbc"},{"c":"orignew"},{"d":"1"},{"e":"ocip"},{"f":"20"},{"g":"y-gencatlg"}]}],"925":[{"0 ":[{"a":"acquire"},{"b":"2 shelf copies"},{"x":"policy default"}]}],"955":[{" ":[{"a":"to HLCD pc03 03-13-00; lh08 to subj. 03-14-00; lh06 03-22-00; lk02 03-22-00; to Dewey 03-22-00; aa05 03-23-00; ps13 2001-11-06 bk rec'd, to CIP ver."},{"f":"pv08 2001-11-07 CIP ver. to BCCD"}]}],"_FORMAT":"MarcXchange","_LEADER":"01488cam 2200349 a 4500","_TYPE":"Bibliographic"},{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"010":[{" ":[{"a":" 2002027497"}]}],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"042":[{" ":[{"a":"lcac"}]}],"050":[{"00":[{"a":"PZ7.C3315"},{"b":"Su 2002"}]}],"082":[{"00":[{"a":"[Fic]"},{"2":"21"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"906":[{" ":[{"a":"7"},{"b":"cbc"},{"c":"orignew"},{"d":"1"},{"e":"ocip"},{"f":"20"},{"g":"y-gencatlg"}]}],"925":[{"0 ":[{"a":"acquire"},{"b":"2 shelf copies"},{"x":"policy default"}]}],"952":[{" ":[{"a":"II lb11 09-05-02"}]}],"955":[{" ":[{"a":["pc14 2002-08-05 to HLCD","ps09 2003-03-04 1 copy rec'd., to CIP ver.","ld11 2003-05-12 cp2 to BCCD"]},{"c":"lh08 2002-08-06 to subj.;"},{"d":"lb11 2002-09-05"},{"e":"lb05 2002-09-06 to cip"},{"f":"pv01 2003-03-17 CIP ver to BCCD"}]}],"_FORMAT":"MarcXchange","_LEADER":"01185cam 2200301 a 4500","_TYPE":"Bibliographic"}]

View file

@ -0,0 +1 @@
[{"001":["11939876"],"005":["20041229190604.0"],"008":["000313s2000 nyu 000 1 eng "],"010":[{" ":[{"a":" 00029063 "}]}],"020":[{" ":[{"a":"0679450041 (acid-free paper)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"043":[{" ":[{"a":"n-us-ny"}]}],"050":[{"00":[{"a":"PS3553.H15"},{"b":"A82 2000"}]}],"082":[{"00":[{"a":"813/.54"},{"2":"21"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"14":[{"a":"The amazing adventures of Kavalier and Clay :"},{"b":"a novel /"},{"c":"Michael Chabon."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Random House,"},{"c":"c2000."}]}],"300":[{" ":[{"a":"639 p. ;"},{"c":"25 cm."}]}],"650":[{" 0":[{"a":"Comic books, strips, etc."},{"x":"Authorship"},{"v":"Fiction."}]},{" 0":[{"a":"Heroes in mass media"},{"v":"Fiction."}]},{" 0":[{"a":"Czech Americans"},{"v":"Fiction."}]},{" 0":[{"a":"Young men"},{"v":"Fiction."}]},{" 0":[{"a":"Cartoonists"},{"v":"Fiction."}]}],"651":[{" 0":[{"a":"New York (N.Y.)"},{"v":"Fiction."}]}],"655":[{" 7":[{"a":"Humorous stories."},{"2":"gsafd"}]},{" 7":[{"a":"Bildungsromane."},{"2":"gsafd"}]}],"856":[{"42":[{"3":"Contributor biographical information"},{"u":"http://www.loc.gov/catdir/bios/random052/00029063.html"}]},{"41":[{"3":"Sample text"},{"u":"http://www.loc.gov/catdir/samples/random044/00029063.html"}]},{"42":[{"3":"Publisher description"},{"u":"http://www.loc.gov/catdir/description/random0411/00029063.html"}]}],"906":[{" ":[{"a":"7"},{"b":"cbc"},{"c":"orignew"},{"d":"1"},{"e":"ocip"},{"f":"20"},{"g":"y-gencatlg"}]}],"925":[{"0 ":[{"a":"acquire"},{"b":"2 shelf copies"},{"x":"policy default"}]}],"955":[{" ":[{"a":"to HLCD pc03 03-13-00; lh08 to subj. 03-14-00; lh06 03-22-00; lk02 03-22-00; to Dewey 03-22-00; aa05 03-23-00; ps13 2001-11-06 bk rec'd, to CIP ver."},{"f":"pv08 2001-11-07 CIP ver. to BCCD"}]}],"_FORMAT":"MarcXchange","_LEADER":"01488cam 2200349 a 4500","_TYPE":"Bibliographic"},{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"010":[{" ":[{"a":" 2002027497"}]}],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"042":[{" ":[{"a":"lcac"}]}],"050":[{"00":[{"a":"PZ7.C3315"},{"b":"Su 2002"}]}],"082":[{"00":[{"a":"[Fic]"},{"2":"21"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"906":[{" ":[{"a":"7"},{"b":"cbc"},{"c":"orignew"},{"d":"1"},{"e":"ocip"},{"f":"20"},{"g":"y-gencatlg"}]}],"925":[{"0 ":[{"a":"acquire"},{"b":"2 shelf copies"},{"x":"policy default"}]}],"952":[{" ":[{"a":"II lb11 09-05-02"}]}],"955":[{" ":[{"a":["pc14 2002-08-05 to HLCD","ps09 2003-03-04 1 copy rec'd., to CIP ver.","ld11 2003-05-12 cp2 to BCCD"]},{"c":"lh08 2002-08-06 to subj.;"},{"d":"lb11 2002-09-05"},{"e":"lb05 2002-09-06 to cip"},{"f":"pv01 2003-03-17 CIP ver to BCCD"}]}],"_FORMAT":"MarcXchange","_LEADER":"01185cam 2200301 a 4500","_TYPE":"Bibliographic"}]

View file

@ -0,0 +1 @@
[{"001":["11939876"],"005":["20041229190604.0"],"008":["000313s2000 nyu 000 1 eng "],"020":[{" ":[{"a":"0679450041 (acid-free paper)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"14":[{"a":"The amazing adventures of Kavalier and Clay :"},{"b":"a novel /"},{"c":"Michael Chabon."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Random House,"},{"c":"c2000."}]}],"300":[{" ":[{"a":"639 p. ;"},{"c":"25 cm."}]}],"650":[{" 0":[{"a":"Comic books, strips, etc."},{"x":"Authorship"},{"v":"Fiction."}]},{" 0":[{"a":"Heroes in mass media"},{"v":"Fiction."}]},{" 0":[{"a":"Czech Americans"},{"v":"Fiction."}]},{" 0":[{"a":"Young men"},{"v":"Fiction."}]},{" 0":[{"a":"Cartoonists"},{"v":"Fiction."}]}],"651":[{" 0":[{"a":"New York (N.Y.)"},{"v":"Fiction."}]}],"655":[{" 7":[{"a":"Humorous stories."},{"2":"gsafd"}]},{" 7":[{"a":"Bildungsromane."},{"2":"gsafd"}]}],"_FORMAT":"MarcXchange","_LEADER":"00759cam a2200229 a 4500","_TYPE":"Bibliographic"},{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"_FORMAT":"MarcXchange","_LEADER":"00714cam a2200205 a 4500","_TYPE":"Bibliographic"}]

View file

@ -0,0 +1 @@
[{"001":["11939876"],"005":["20041229190604.0"],"008":["000313s2000 nyu 000 1 eng "],"020":[{" ":[{"a":"0679450041 (acid-free paper)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"14":[{"a":"The amazing adventures of Kavalier and Clay :"},{"b":"a novel /"},{"c":"Michael Chabon."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Random House,"},{"c":"c2000."}]}],"300":[{" ":[{"a":"639 p. ;"},{"c":"25 cm."}]}],"650":[{" 0":[{"a":"Comic books, strips, etc."},{"x":"Authorship"},{"v":"Fiction."}]},{" 0":[{"a":"Heroes in mass media"},{"v":"Fiction."}]},{" 0":[{"a":"Czech Americans"},{"v":"Fiction."}]},{" 0":[{"a":"Young men"},{"v":"Fiction."}]},{" 0":[{"a":"Cartoonists"},{"v":"Fiction."}]}],"651":[{" 0":[{"a":"New York (N.Y.)"},{"v":"Fiction."}]}],"655":[{" 7":[{"a":"Humorous stories."},{"2":"gsafd"}]},{" 7":[{"a":"Bildungsromane."},{"2":"gsafd"}]}],"_FORMAT":"MarcXchange","_LEADER":"00759cam a2200229 a 4500","_TYPE":"Bibliographic"},{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"_FORMAT":"MarcXchange","_LEADER":"00714cam a2200205 a 4500","_TYPE":"Bibliographic"}]

View file

@ -0,0 +1 @@
[{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"_FORMAT":"MarcXchange","_LEADER":"00714cam a2200205 a 4500","_TYPE":"Bibliographic"}]

View file

@ -0,0 +1 @@
[{"001":["12883376"],"005":["20030616111422.0"],"008":["020805s2002 nyu j 000 1 eng "],"020":[{" ":[{"a":"0786808772"}]},{" ":[{"a":"0786816155 (pbk.)"}]}],"040":[{" ":[{"a":"DLC"},{"c":"DLC"},{"d":"DLC"}]}],"100":[{"1 ":[{"a":"Chabon, Michael."}]}],"245":[{"10":[{"a":"Summerland /"},{"c":"Michael Chabon."}]}],"250":[{" ":[{"a":"1st ed."}]}],"260":[{" ":[{"a":"New York :"},{"b":"Miramax Books/Hyperion Books for Children,"},{"c":"c2002."}]}],"300":[{" ":[{"a":"500 p. ;"},{"c":"22 cm."}]}],"520":[{" ":[{"a":"Ethan Feld, the worst baseball player in the history of the game, finds himself recruited by a 100-year-old scout to help a band of fairies triumph over an ancient enemy."}]}],"650":[{" 1":[{"a":"Fantasy."}]},{" 1":[{"a":"Baseball"},{"v":"Fiction."}]},{" 1":[{"a":"Magic"},{"v":"Fiction."}]}],"_FORMAT":"MarcXchange","_LEADER":"00714cam a2200205 a 4500","_TYPE":"Bibliographic"}]