add stable field order in record building, use delegate map in MarcRecord, more filters for field processing in MarcRecord
This commit is contained in:
parent
34ae0b53a3
commit
28b9a2d86d
21 changed files with 249 additions and 89 deletions
|
@ -1,5 +1,5 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = marc
|
name = marc
|
||||||
version = 2.8.0
|
version = 2.9.0
|
||||||
|
|
||||||
org.gradle.warning.mode = ALL
|
org.gradle.warning.mode = ALL
|
||||||
|
|
|
@ -15,13 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package org.xbib.marc;
|
package org.xbib.marc;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class LightweightMarcRecordAdapter extends MarcRecordAdapter {
|
public class LightweightMarcRecordAdapter extends MarcRecordAdapter {
|
||||||
|
|
||||||
public LightweightMarcRecordAdapter(MarcRecordListener marcRecordListener) {
|
public LightweightMarcRecordAdapter(MarcRecordListener marcRecordListener) {
|
||||||
super(marcRecordListener);
|
super(marcRecordListener, false);
|
||||||
this.builder = Marc.builder().lightweightRecord();
|
this.builder = Marc.builder().lightweightRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -662,7 +662,9 @@ public final class Marc {
|
||||||
|
|
||||||
private MarcGenerator marcGenerator;
|
private MarcGenerator marcGenerator;
|
||||||
|
|
||||||
private boolean islightweightRecord;
|
private boolean isLightweightRecord;
|
||||||
|
|
||||||
|
private boolean isStableFieldOrder;
|
||||||
|
|
||||||
private Pattern keyPattern;
|
private Pattern keyPattern;
|
||||||
|
|
||||||
|
@ -1116,8 +1118,8 @@ public final class Marc {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Marc.Builder addField(MarcField marcField) {
|
public Marc.Builder addField(MarcField marcField) {
|
||||||
boolean keymatch = keyPattern == null || marcField.matchKey(keyPattern) != null;
|
boolean keymatch = keyPattern == null || marcField.matchesKey(keyPattern);
|
||||||
boolean valuematch = valuePattern == null || marcField.matchValue(valuePattern) != null;
|
boolean valuematch = valuePattern == null || marcField.matchesValue(valuePattern);
|
||||||
if (keymatch && valuematch) {
|
if (keymatch && valuematch) {
|
||||||
this.marcFieldList.add(marcField);
|
this.marcFieldList.add(marcField);
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1127,12 @@ public final class Marc {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Marc.Builder lightweightRecord() {
|
public Marc.Builder lightweightRecord() {
|
||||||
this.islightweightRecord = true;
|
this.isLightweightRecord = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Marc.Builder stableFieldOrder() {
|
||||||
|
this.isStableFieldOrder = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,7 +1141,7 @@ public final class Marc {
|
||||||
* @return MARC record
|
* @return MARC record
|
||||||
*/
|
*/
|
||||||
public MarcRecord buildRecord() {
|
public MarcRecord buildRecord() {
|
||||||
return new MarcRecord(format, type, recordLabel, marcFieldList, islightweightRecord);
|
return new MarcRecord(format, type, recordLabel, marcFieldList, isLightweightRecord, isStableFieldOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -199,8 +199,8 @@ public class MarcField implements Comparable<MarcField> {
|
||||||
* @param pattern the pattern
|
* @param pattern the pattern
|
||||||
* @return this MARC field if pattern macthes, otherwise null
|
* @return this MARC field if pattern macthes, otherwise null
|
||||||
*/
|
*/
|
||||||
public MarcField matchKey(Pattern pattern) {
|
public boolean matchesKey(Pattern pattern) {
|
||||||
return pattern.matcher(toTagIndicatorKey()).matches() ? this : null;
|
return pattern.matcher(toTagIndicatorKey()).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,16 +208,16 @@ public class MarcField implements Comparable<MarcField> {
|
||||||
* @param pattern the pattern to match
|
* @param pattern the pattern to match
|
||||||
* @return thhis MARC field if pattern matches, or null if not
|
* @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()) {
|
if (builder.value != null && pattern.matcher(builder.value).matches()) {
|
||||||
return this;
|
return true;
|
||||||
}
|
}
|
||||||
for (Subfield subfield : builder.subfields) {
|
for (Subfield subfield : builder.subfields) {
|
||||||
if (pattern.matcher(subfield.getValue()).matches()) {
|
if (pattern.matcher(subfield.getValue()).matches()) {
|
||||||
return this;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
8
src/main/java/org/xbib/marc/MarcFieldHandler.java
Normal file
8
src/main/java/org/xbib/marc/MarcFieldHandler.java
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package org.xbib.marc;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface MarcFieldHandler {
|
||||||
|
|
||||||
|
void field(MarcField marcField);
|
||||||
|
|
||||||
|
}
|
|
@ -26,19 +26,21 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.BiConsumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MARC record. This is an extended MARC record augmented with MarcXchange information.
|
* A MARC record. This is an extended MARC record augmented with MarcXchange information.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
public class MarcRecord implements Map<String, Object> {
|
||||||
public class MarcRecord extends LinkedHashMap<String, Object> {
|
|
||||||
|
|
||||||
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
|
private static final MarcRecord EMPTY_RECORD = Marc.builder().buildRecord();
|
||||||
|
|
||||||
|
private final Map<String, Object> delegate;
|
||||||
|
|
||||||
private String format;
|
private String format;
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
|
@ -47,8 +49,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
|
|
||||||
private final transient List<MarcField> marcFields;
|
private final transient List<MarcField> marcFields;
|
||||||
|
|
||||||
private MarcRecord(Map<String, Object> map) {
|
private MarcRecord(Map<String, Object> delegate) {
|
||||||
super(map);
|
this.delegate = delegate;
|
||||||
this.marcFields = new LinkedList<>();
|
this.marcFields = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +67,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
String type,
|
String type,
|
||||||
RecordLabel recordLabel,
|
RecordLabel recordLabel,
|
||||||
List<MarcField> marcFields,
|
List<MarcField> marcFields,
|
||||||
boolean lightweight) {
|
boolean lightweight,
|
||||||
super();
|
boolean stable) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.recordLabel = recordLabel;
|
this.recordLabel = recordLabel;
|
||||||
|
@ -74,9 +76,7 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
throw new NullPointerException("record label must not be null");
|
throw new NullPointerException("record label must not be null");
|
||||||
}
|
}
|
||||||
this.marcFields = marcFields;
|
this.marcFields = marcFields;
|
||||||
if (!lightweight) {
|
this.delegate = lightweight ? Map.of() : createMap(stable);
|
||||||
createMap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,9 +97,8 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
String leaderTag,
|
String leaderTag,
|
||||||
RecordLabel recordLabel) {
|
RecordLabel recordLabel) {
|
||||||
MarcRecord marcRecord = new MarcRecord(map);
|
MarcRecord marcRecord = new MarcRecord(map);
|
||||||
marcRecord.parseMap(map, ".", "", (key, value) -> {
|
marcRecord.parseMap(map, ".", "", (key, value) ->
|
||||||
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build());
|
marcRecord.marcFields.add(MarcField.builder().key(key, "\\.", value.toString()).build()));
|
||||||
});
|
|
||||||
if (map.containsKey(formatTag)) {
|
if (map.containsKey(formatTag)) {
|
||||||
marcRecord.format = map.get(formatTag).toString();
|
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
|
* @param tag the MARC tag
|
||||||
* @return the MARC field list matching the given tag.
|
|
||||||
*/
|
*/
|
||||||
public List<MarcField> getFields(String tag) {
|
public void filter(String tag, MarcFieldHandler handler) {
|
||||||
return marcFields.stream().filter(marcField -> marcField.getTag().equals(tag))
|
filter(marcField -> marcField.getTag().equals(tag), handler);
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void filter(String tag, String indicator, MarcFieldHandler handler) {
|
||||||
* Return a list of MARC fields of this record where key pattern matches were found.
|
filter(marcField -> marcField.getTag().equals(tag) && marcField.getIndicator().equals(indicator), handler);
|
||||||
*
|
|
||||||
* @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, String subfieldId, MarcFieldHandler handler) {
|
||||||
* Return a list of MARC fields of this record where pattern matches were found.
|
filter(marcField -> marcField.getTag().equals(tag) &&
|
||||||
*
|
marcField.getIndicator().equals(indicator) &&
|
||||||
* @param pattern the pattern
|
marcField.getSubfieldIds().contains(subfieldId), handler);
|
||||||
* @return a list of MARC fields
|
}
|
||||||
*/
|
|
||||||
public List<MarcField> filterValue(Pattern pattern) {
|
public void filter(Pattern pattern, MarcFieldHandler handler) {
|
||||||
return marcFields.stream().map(field ->
|
filter(field -> field.matchesKey(pattern), handler);
|
||||||
field.matchValue(pattern)).filter(Objects::nonNull).collect(Collectors.toList());
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
|
@ -197,21 +292,26 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
return (recordLabel.toString() + marcFields.toString()).hashCode();
|
return (recordLabel.toString() + marcFields.toString()).hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return delegate.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void createMap() {
|
private Map<String, Object> createMap(boolean stable) {
|
||||||
put(FORMAT_TAG, format);
|
Map<String, Object> map = stable ? new TreeMap<>() : new LinkedHashMap<>();
|
||||||
put(TYPE_TAG, type);
|
map.put(FORMAT_TAG, format);
|
||||||
put(LEADER_TAG, recordLabel.toString());
|
map.put(TYPE_TAG, type);
|
||||||
|
map.put(LEADER_TAG, recordLabel.toString());
|
||||||
for (MarcField marcField : marcFields) {
|
for (MarcField marcField : marcFields) {
|
||||||
String tag = marcField.getTag();
|
String tag = marcField.getTag();
|
||||||
int repeat;
|
int repeat;
|
||||||
Map<String, Object> repeatMap;
|
Map<String, Object> repeatMap;
|
||||||
if (!containsKey(tag)) {
|
if (!map.containsKey(tag)) {
|
||||||
repeatMap = new LinkedHashMap<>();
|
repeatMap = new LinkedHashMap<>();
|
||||||
repeat = 1;
|
repeat = 1;
|
||||||
put(tag, repeatMap);
|
map.put(tag, repeatMap);
|
||||||
} else {
|
} else {
|
||||||
repeatMap = (Map<String, Object>) get(tag);
|
repeatMap = (Map<String, Object>) map.get(tag);
|
||||||
repeat = repeatMap.size() + 1;
|
repeat = repeatMap.size() + 1;
|
||||||
}
|
}
|
||||||
String indicator = marcField.getIndicator();
|
String indicator = marcField.getIndicator();
|
||||||
|
@ -246,6 +346,7 @@ public class MarcRecord extends LinkedHashMap<String, Object> {
|
||||||
repeatMap.put(Integer.toString(repeat), marcField.getValue());
|
repeatMap.put(Integer.toString(repeat), marcField.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -28,9 +28,15 @@ public class MarcRecordAdapter implements MarcListener {
|
||||||
|
|
||||||
protected Marc.Builder builder;
|
protected Marc.Builder builder;
|
||||||
|
|
||||||
public MarcRecordAdapter(MarcRecordListener marcRecordListener) {
|
private boolean isStableFieldOrder;
|
||||||
|
|
||||||
|
public MarcRecordAdapter(MarcRecordListener marcRecordListener, boolean isStableFieldOrder) {
|
||||||
this.marcRecordListener = marcRecordListener;
|
this.marcRecordListener = marcRecordListener;
|
||||||
this.builder = Marc.builder();
|
this.builder = Marc.builder();
|
||||||
|
this.isStableFieldOrder = isStableFieldOrder;
|
||||||
|
if (isStableFieldOrder) {
|
||||||
|
this.builder.stableFieldOrder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,6 +64,9 @@ public class MarcRecordAdapter implements MarcListener {
|
||||||
public void endRecord() {
|
public void endRecord() {
|
||||||
marcRecordListener.record(builder.buildRecord());
|
marcRecordListener.record(builder.buildRecord());
|
||||||
builder = Marc.builder();
|
builder = Marc.builder();
|
||||||
|
if (isStableFieldOrder) {
|
||||||
|
builder.stableFieldOrder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
7
src/main/java/org/xbib/marc/MarcRecordHandler.java
Normal file
7
src/main/java/org/xbib/marc/MarcRecordHandler.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package org.xbib.marc;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface MarcRecordHandler {
|
||||||
|
|
||||||
|
void record(MarcRecord marcRecord);
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
package org.xbib.marc;
|
package org.xbib.marc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for catching MARC records.
|
* Interface for handling MARC records in collections.
|
||||||
*/
|
*/
|
||||||
public interface MarcRecordListener {
|
public interface MarcRecordListener {
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class MabXMLContentHandler extends MarcContentHandler implements MabXMLCo
|
||||||
}
|
}
|
||||||
case FELD: {
|
case FELD: {
|
||||||
String s = content.toString();
|
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) {
|
if (marcValueTransformers != null) {
|
||||||
marcField = marcValueTransformers.transformValue(marcField);
|
marcField = marcValueTransformers.transformValue(marcField);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ public class MabXMLContentHandler extends MarcContentHandler implements MabXMLCo
|
||||||
}
|
}
|
||||||
case UF: {
|
case UF: {
|
||||||
String s = content.toString();
|
String s = content.toString();
|
||||||
stack.peek().subfieldValue(trim ? s.trim() : s);
|
stack.peek().subfieldValue(isTrim ? s.trim() : s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -51,6 +51,7 @@ public enum TypeOfControl {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
case '#':
|
case '#':
|
||||||
|
case '0':
|
||||||
return UNSPECIFIED;
|
return UNSPECIFIED;
|
||||||
case 'a':
|
case 'a':
|
||||||
return ARCHIVAL;
|
return ARCHIVAL;
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class MarcContentHandler
|
||||||
|
|
||||||
protected MarcValueTransformers marcValueTransformers;
|
protected MarcValueTransformers marcValueTransformers;
|
||||||
|
|
||||||
protected boolean trim;
|
protected boolean isTrim;
|
||||||
|
|
||||||
private MarcFieldTransformers marcFieldTransformers;
|
private MarcFieldTransformers marcFieldTransformers;
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ public class MarcContentHandler
|
||||||
|
|
||||||
private final Set<String> validNamespaces;
|
private final Set<String> validNamespaces;
|
||||||
|
|
||||||
|
private boolean isStableFieldOrder;
|
||||||
|
|
||||||
public MarcContentHandler() {
|
public MarcContentHandler() {
|
||||||
this.recordCounter = new AtomicInteger();
|
this.recordCounter = new AtomicInteger();
|
||||||
this.stack = new LinkedList<>();
|
this.stack = new LinkedList<>();
|
||||||
|
@ -160,7 +162,12 @@ public class MarcContentHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
public MarcContentHandler setTrim(boolean trim) {
|
public MarcContentHandler setTrim(boolean trim) {
|
||||||
this.trim = trim;
|
this.isTrim = trim;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarcContentHandler setStableFieldOrder(boolean stableFieldOrder) {
|
||||||
|
this.isStableFieldOrder = stableFieldOrder;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +254,7 @@ public class MarcContentHandler
|
||||||
} else {
|
} else {
|
||||||
MarcRecord marcRecord = new MarcRecord(getFormat(), getType(),
|
MarcRecord marcRecord = new MarcRecord(getFormat(), getType(),
|
||||||
RecordLabel.builder().from(label).build(),
|
RecordLabel.builder().from(label).build(),
|
||||||
marcFieldList, false);
|
marcFieldList, false, isStableFieldOrder);
|
||||||
marcRecordListener.record(marcRecord);
|
marcRecordListener.record(marcRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,7 +412,7 @@ public class MarcContentHandler
|
||||||
}
|
}
|
||||||
case SUBFIELD: {
|
case SUBFIELD: {
|
||||||
String s = content.toString();
|
String s = content.toString();
|
||||||
stack.peek().subfieldValue(trim ? s.trim() : s);
|
stack.peek().subfieldValue(isTrim ? s.trim() : s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -21,6 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.junit.jupiter.api.Test;
|
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.label.RecordLabel;
|
||||||
import org.xbib.marc.transformer.value.MarcValueTransformers;
|
import org.xbib.marc.transformer.value.MarcValueTransformers;
|
||||||
import org.xbib.marc.xml.MarcXchangeWriter;
|
import org.xbib.marc.xml.MarcXchangeWriter;
|
||||||
|
@ -29,7 +31,10 @@ import java.io.InputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.Normalizer;
|
import java.text.Normalizer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -97,7 +102,10 @@ public class MarcRecordTest {
|
||||||
// only single record
|
// only single record
|
||||||
for (MarcRecord marcRecord : builder.iterable()) {
|
for (MarcRecord marcRecord : builder.iterable()) {
|
||||||
// single 245 field
|
// 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
|
@Test
|
||||||
public void testFilterValue() throws Exception {
|
public void testFilterValue() throws Exception {
|
||||||
String s = "summerland.mrc";
|
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("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"));
|
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")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class MarcJsonWriterTest {
|
||||||
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
||||||
) {
|
) {
|
||||||
Marc.builder()
|
Marc.builder()
|
||||||
|
.stableFieldOrder()
|
||||||
.setInputStream(inputStream)
|
.setInputStream(inputStream)
|
||||||
.setCharset(Charset.forName("ANSEL"))
|
.setCharset(Charset.forName("ANSEL"))
|
||||||
.setMarcListener(writer)
|
.setMarcListener(writer)
|
||||||
|
@ -78,10 +79,11 @@ public class MarcJsonWriterTest {
|
||||||
"chabon.mrc",
|
"chabon.mrc",
|
||||||
"chabon-loc.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)
|
try (MarcJsonWriter writer = new MarcJsonWriter(outputStream)
|
||||||
) {
|
) {
|
||||||
Marc.builder()
|
Marc.builder()
|
||||||
|
.stableFieldOrder()
|
||||||
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
|
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
|
||||||
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
||||||
.setInputStream(inputStream)
|
.setInputStream(inputStream)
|
||||||
|
@ -107,14 +109,14 @@ public class MarcJsonWriterTest {
|
||||||
"chabon.mrc",
|
"chabon.mrc",
|
||||||
"chabon-loc.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)) {
|
try (MarcJsonWriter writer = new MarcJsonWriter(outputStream)) {
|
||||||
Marc.builder()
|
Marc.builder()
|
||||||
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
|
.setFormat(MarcXchangeConstants.MARCXCHANGE_FORMAT)
|
||||||
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
.setType(MarcXchangeConstants.BIBLIOGRAPHIC_TYPE)
|
||||||
.setInputStream(inputStream)
|
.setInputStream(inputStream)
|
||||||
.setCharset(Charset.forName("ANSEL"))
|
.setCharset(Charset.forName("ANSEL"))
|
||||||
.setMarcListener(new MarcRecordAdapter(writer))
|
.setMarcListener(new MarcRecordAdapter(writer, true))
|
||||||
.build()
|
.build()
|
||||||
.writeCollection();
|
.writeCollection();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +136,7 @@ public class MarcJsonWriterTest {
|
||||||
contentHandler.addNamespace("http://www.ddb.de/professionell/mabxml/mabxml-1.xsd");
|
contentHandler.addNamespace("http://www.ddb.de/professionell/mabxml/mabxml-1.xsd");
|
||||||
contentHandler.setFormat("MARC21");
|
contentHandler.setFormat("MARC21");
|
||||||
contentHandler.setType("Bibliographic");
|
contentHandler.setType("Bibliographic");
|
||||||
contentHandler.setMarcListener(new MarcRecordAdapter(writer));
|
contentHandler.setMarcListener(new MarcRecordAdapter(writer, true));
|
||||||
Marc.builder()
|
Marc.builder()
|
||||||
.setInputStream(inputStream)
|
.setInputStream(inputStream)
|
||||||
.setContentHandler(contentHandler)
|
.setContentHandler(contentHandler)
|
||||||
|
|
|
@ -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"}
|
|
@ -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"}]
|
|
@ -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"}]
|
|
@ -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"}]
|
|
@ -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"}]
|
|
@ -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"}]
|
|
@ -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"}]
|
Loading…
Reference in a new issue