Skip to content

Commit 21c84fa

Browse files
committed
Make emitting MARCXML namespace configurable.
Fixes #403.
1 parent 5a0d393 commit 21c84fa

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,35 @@
4040
@FluxCommand("encode-marcxml")
4141
public final class MarcXmlEncoder extends DefaultStreamPipe<ObjectReceiver<String>> {
4242

43-
private static final String ROOT_OPEN = "<marc:collection xmlns:marc=\"http://www.loc.gov/MARC21/slim\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\">";
44-
private static final String ROOT_CLOSE = "</marc:collection>";
43+
private static final String NAMESPACE = "http://www.loc.gov/MARC21/slim";
44+
private static final String NAMESPACE_NAME = "marc";
45+
/*package-private*/ static final String NAMESPACE_PREFIX = NAMESPACE_NAME + ":";
46+
private static final String NAMESPACE_SUFFIX = ":" + NAMESPACE_NAME;
4547

46-
private static final String RECORD_OPEN = "<marc:record>";
47-
private static final String RECORD_CLOSE = "</marc:record>";
48+
private static final String SCHEMA_ATTRIBUTES = " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"" + NAMESPACE + " http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\"";
49+
50+
/*package-private*/ static final String ROOT_OPEN_TEMPLATE = "<%scollection xmlns%s=\"" + NAMESPACE + "\"%s>";
51+
private static final String ROOT_CLOSE_TEMPLATE = "</%scollection>";
52+
53+
private static final String RECORD_OPEN_TEMPLATE = "<%srecord>";
54+
private static final String RECORD_CLOSE_TEMPLATE = "</%srecord>";
4855

4956
private static final String ATTRIBUTE_TEMPLATE = " %s=\"%s\"";
5057

51-
private static final String CONTROLFIELD_OPEN_TEMPLATE = "<marc:controlfield tag=\"%s\">";
52-
private static final String CONTROLFIELD_CLOSE = "</marc:controlfield>";
58+
private static final String CONTROLFIELD_OPEN_TEMPLATE = "<%scontrolfield tag=\"%s\">";
59+
private static final String CONTROLFIELD_CLOSE_TEMPLATE = "</%scontrolfield>";
5360

54-
private static final String DATAFIELD_OPEN_TEMPLATE = "<marc:datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">";
55-
private static final String DATAFIELD_CLOSE = "</marc:datafield>";
61+
private static final String DATAFIELD_OPEN_TEMPLATE = "<%sdatafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">";
62+
private static final String DATAFIELD_CLOSE_TEMPLATE = "</%sdatafield>";
5663

57-
private static final String SUBFIELD_OPEN_TEMPLATE = "<marc:subfield code=\"%s\">";
58-
private static final String SUBFIELD_CLOSE = "</marc:subfield>";
64+
private static final String SUBFIELD_OPEN_TEMPLATE = "<%ssubfield code=\"%s\">";
65+
private static final String SUBFIELD_CLOSE_TEMPLATE = "</%ssubfield>";
5966

60-
private static final String LEADER_OPEN_TEMPLATE = "<marc:leader>";
61-
private static final String LEADER_CLOSE_TEMPLATE = "</marc:leader>";
67+
private static final String LEADER_TEMPLATE = "<%sleader>%s</%sleader>";
6268

6369
private static final String NEW_LINE = "\n";
6470
private static final String INDENT = "\t";
71+
private static final String EMPTY = "";
6572

6673
private static final String XML_DECLARATION_TEMPLATE = "<?xml version=\"%s\" encoding=\"%s\"?>";
6774

@@ -82,6 +89,9 @@ public final class MarcXmlEncoder extends DefaultStreamPipe<ObjectReceiver<Strin
8289
private String xmlVersion;
8390
private String xmlEncoding;
8491

92+
private boolean emitNamespace;
93+
private String namespacePrefix;
94+
8595
private String currentEntity;
8696
private int indentationLevel;
8797
private int recordAttributeOffset;
@@ -99,6 +109,13 @@ public MarcXmlEncoder() {
99109

100110
this.indentationLevel = 0;
101111
this.formatted = true;
112+
113+
setEmitNamespace(true);
114+
}
115+
116+
public void setEmitNamespace(final boolean emitNamespace) {
117+
this.emitNamespace = emitNamespace;
118+
namespacePrefix = emitNamespace ? NAMESPACE_PREFIX : EMPTY;
102119
}
103120

104121
public void omitXmlDeclaration(final boolean currentOmitXmlDeclaration) {
@@ -130,14 +147,16 @@ public void startRecord(final String identifier) {
130147
writeHeader();
131148
prettyPrintNewLine();
132149
}
133-
writeRaw(ROOT_OPEN);
150+
writeRaw(String.format(ROOT_OPEN_TEMPLATE, namespacePrefix,
151+
emitNamespace ? NAMESPACE_SUFFIX : EMPTY,
152+
emitNamespace ? SCHEMA_ATTRIBUTES : EMPTY));
134153
prettyPrintNewLine();
135154
incrementIndentationLevel();
136155
}
137156
atStreamStart = false;
138157

139158
prettyPrintIndentation();
140-
writeRaw(RECORD_OPEN);
159+
writeRaw(String.format(RECORD_OPEN_TEMPLATE, namespacePrefix));
141160
recordAttributeOffset = builder.length() - 1;
142161
prettyPrintNewLine();
143162

@@ -148,7 +167,7 @@ public void startRecord(final String identifier) {
148167
public void endRecord() {
149168
decrementIndentationLevel();
150169
prettyPrintIndentation();
151-
writeRaw(RECORD_CLOSE);
170+
writeRaw(String.format(RECORD_CLOSE_TEMPLATE, namespacePrefix));
152171
prettyPrintNewLine();
153172
sendAndClearData();
154173
}
@@ -167,7 +186,7 @@ public void startEntity(final String name) {
167186
final String ind1 = name.substring(IND1_BEGIN, IND1_END);
168187
final String ind2 = name.substring(IND2_BEGIN, IND2_END);
169188
prettyPrintIndentation();
170-
writeRaw(String.format(DATAFIELD_OPEN_TEMPLATE, tag, ind1, ind2));
189+
writeRaw(String.format(DATAFIELD_OPEN_TEMPLATE, namespacePrefix, tag, ind1, ind2));
171190
prettyPrintNewLine();
172191
incrementIndentationLevel();
173192
}
@@ -178,7 +197,7 @@ public void endEntity() {
178197
if (!currentEntity.equals(Marc21EventNames.LEADER_ENTITY)) {
179198
decrementIndentationLevel();
180199
prettyPrintIndentation();
181-
writeRaw(DATAFIELD_CLOSE);
200+
writeRaw(String.format(DATAFIELD_CLOSE_TEMPLATE, namespacePrefix));
182201
prettyPrintNewLine();
183202
}
184203
currentEntity = "";
@@ -194,19 +213,19 @@ public void literal(final String name, final String value) {
194213
}
195214
else if (!writeLeader(name, value)) {
196215
prettyPrintIndentation();
197-
writeRaw(String.format(CONTROLFIELD_OPEN_TEMPLATE, name));
216+
writeRaw(String.format(CONTROLFIELD_OPEN_TEMPLATE, namespacePrefix, name));
198217
if (value != null) {
199218
writeEscaped(value.trim());
200219
}
201-
writeRaw(CONTROLFIELD_CLOSE);
220+
writeRaw(String.format(CONTROLFIELD_CLOSE_TEMPLATE, namespacePrefix));
202221
prettyPrintNewLine();
203222
}
204223
}
205224
else if (!writeLeader(currentEntity, value)) {
206225
prettyPrintIndentation();
207-
writeRaw(String.format(SUBFIELD_OPEN_TEMPLATE, name));
226+
writeRaw(String.format(SUBFIELD_OPEN_TEMPLATE, namespacePrefix, name));
208227
writeEscaped(value.trim());
209-
writeRaw(SUBFIELD_CLOSE);
228+
writeRaw(String.format(SUBFIELD_CLOSE_TEMPLATE, namespacePrefix));
210229
prettyPrintNewLine();
211230
}
212231
}
@@ -243,7 +262,7 @@ private void writeHeader() {
243262

244263
/** Closes the root tag */
245264
private void writeFooter() {
246-
writeRaw(ROOT_CLOSE);
265+
writeRaw(String.format(ROOT_CLOSE_TEMPLATE, namespacePrefix));
247266
}
248267

249268
/** Writes a unescaped sequence */
@@ -259,7 +278,7 @@ private void writeEscaped(final String str) {
259278
private boolean writeLeader(final String name, final String value) {
260279
if (name.equals(Marc21EventNames.LEADER_ENTITY)) {
261280
prettyPrintIndentation();
262-
writeRaw(LEADER_OPEN_TEMPLATE + value + LEADER_CLOSE_TEMPLATE);
281+
writeRaw(String.format(LEADER_TEMPLATE, namespacePrefix, value, namespacePrefix));
263282
prettyPrintNewLine();
264283

265284
return true;

metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ public void createTwoRecordsInOneCollection() {
168168
assertEquals(expected, actual);
169169
}
170170

171+
@Test
172+
public void issue403_shouldNotEmitNamespaceIfDisabled() {
173+
encoder.setEmitNamespace(false);
174+
addOneRecord(encoder);
175+
addOneRecord(encoder);
176+
encoder.closeStream();
177+
String expected = XML_DECLARATION + String.format(MarcXmlEncoder.ROOT_OPEN_TEMPLATE, "", "", "") + XML_RECORD + XML_RECORD + XML_MARC_COLLECTION_END_TAG;
178+
String actual = resultCollector.toString();
179+
assertEquals(expected.replace(MarcXmlEncoder.NAMESPACE_PREFIX, ""), actual);
180+
}
181+
171182
@Test(expected = MetafactureException.class)
172183
public void emitExceptionWhenEntityLengthNot5() {
173184
encoder.startRecord(RECORD_ID);

0 commit comments

Comments
 (0)