From 21c84faf603a19a991edc595bab850dde7098487 Mon Sep 17 00:00:00 2001 From: Jens Wille Date: Fri, 15 Oct 2021 20:20:38 +0200 Subject: [PATCH 1/2] Make emitting MARCXML namespace configurable. Fixes #403. --- .../biblio/marc21/MarcXmlEncoder.java | 65 ++++++++++++------- .../biblio/marc21/MarcXmlEncoderTest.java | 11 ++++ 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java index 1935569b7..919dac144 100644 --- a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java +++ b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java @@ -40,28 +40,35 @@ @FluxCommand("encode-marcxml") public final class MarcXmlEncoder extends DefaultStreamPipe> { - private static final String ROOT_OPEN = ""; - private static final String ROOT_CLOSE = ""; + private static final String NAMESPACE = "http://www.loc.gov/MARC21/slim"; + private static final String NAMESPACE_NAME = "marc"; + /*package-private*/ static final String NAMESPACE_PREFIX = NAMESPACE_NAME + ":"; + private static final String NAMESPACE_SUFFIX = ":" + NAMESPACE_NAME; - private static final String RECORD_OPEN = ""; - private static final String RECORD_CLOSE = ""; + 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\""; + + /*package-private*/ static final String ROOT_OPEN_TEMPLATE = "<%scollection xmlns%s=\"" + NAMESPACE + "\"%s>"; + private static final String ROOT_CLOSE_TEMPLATE = ""; + + private static final String RECORD_OPEN_TEMPLATE = "<%srecord>"; + private static final String RECORD_CLOSE_TEMPLATE = ""; private static final String ATTRIBUTE_TEMPLATE = " %s=\"%s\""; - private static final String CONTROLFIELD_OPEN_TEMPLATE = ""; - private static final String CONTROLFIELD_CLOSE = ""; + private static final String CONTROLFIELD_OPEN_TEMPLATE = "<%scontrolfield tag=\"%s\">"; + private static final String CONTROLFIELD_CLOSE_TEMPLATE = ""; - private static final String DATAFIELD_OPEN_TEMPLATE = ""; - private static final String DATAFIELD_CLOSE = ""; + private static final String DATAFIELD_OPEN_TEMPLATE = "<%sdatafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">"; + private static final String DATAFIELD_CLOSE_TEMPLATE = ""; - private static final String SUBFIELD_OPEN_TEMPLATE = ""; - private static final String SUBFIELD_CLOSE = ""; + private static final String SUBFIELD_OPEN_TEMPLATE = "<%ssubfield code=\"%s\">"; + private static final String SUBFIELD_CLOSE_TEMPLATE = ""; - private static final String LEADER_OPEN_TEMPLATE = ""; - private static final String LEADER_CLOSE_TEMPLATE = ""; + private static final String LEADER_TEMPLATE = "<%sleader>%s"; private static final String NEW_LINE = "\n"; private static final String INDENT = "\t"; + private static final String EMPTY = ""; private static final String XML_DECLARATION_TEMPLATE = ""; @@ -82,6 +89,9 @@ public final class MarcXmlEncoder extends DefaultStreamPipe Date: Mon, 18 Oct 2021 17:44:12 +0200 Subject: [PATCH 2/2] Simplify MARCXML tag definition. - Open and close tag are derived from a single definition. - Writing call sites are simplified (`writeRaw` -> `writeTag`). --- .../biblio/marc21/MarcXmlEncoder.java | 85 ++++++++++++------- .../biblio/marc21/MarcXmlEncoderTest.java | 5 +- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java index 919dac144..9a1e6e9f6 100644 --- a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java +++ b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java @@ -25,7 +25,9 @@ import org.metafacture.framework.annotations.Out; import org.metafacture.framework.helpers.DefaultStreamPipe; +import java.util.Arrays; import java.util.Collections; +import java.util.function.Function; /** * Encodes a stream into MARCXML. @@ -40,31 +42,44 @@ @FluxCommand("encode-marcxml") public final class MarcXmlEncoder extends DefaultStreamPipe> { - private static final String NAMESPACE = "http://www.loc.gov/MARC21/slim"; - private static final String NAMESPACE_NAME = "marc"; - /*package-private*/ static final String NAMESPACE_PREFIX = NAMESPACE_NAME + ":"; - private static final String NAMESPACE_SUFFIX = ":" + NAMESPACE_NAME; + private enum Tag { - 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\""; + collection(" xmlns%s=\"" + NAMESPACE + "\"%s"), + controlfield(" tag=\"%s\""), + datafield(" tag=\"%s\" ind1=\"%s\" ind2=\"%s\""), + leader(""), + record(""), + subfield(" code=\"%s\""); - /*package-private*/ static final String ROOT_OPEN_TEMPLATE = "<%scollection xmlns%s=\"" + NAMESPACE + "\"%s>"; - private static final String ROOT_CLOSE_TEMPLATE = ""; + private static final String OPEN_TEMPLATE = "<%%s%s%s>"; + private static final String CLOSE_TEMPLATE = ""; - private static final String RECORD_OPEN_TEMPLATE = "<%srecord>"; - private static final String RECORD_CLOSE_TEMPLATE = ""; + private final String openTemplate; + private final String closeTemplate; - private static final String ATTRIBUTE_TEMPLATE = " %s=\"%s\""; + Tag(final String template) { + openTemplate = String.format(OPEN_TEMPLATE, name(), template); + closeTemplate = String.format(CLOSE_TEMPLATE, name()); + } + + public String open(final Object[] args) { + return String.format(openTemplate, args); + } + + public String close(final Object[] args) { + return String.format(closeTemplate, args); + } - private static final String CONTROLFIELD_OPEN_TEMPLATE = "<%scontrolfield tag=\"%s\">"; - private static final String CONTROLFIELD_CLOSE_TEMPLATE = ""; + } - private static final String DATAFIELD_OPEN_TEMPLATE = "<%sdatafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">"; - private static final String DATAFIELD_CLOSE_TEMPLATE = ""; + private static final String NAMESPACE = "http://www.loc.gov/MARC21/slim"; + private static final String NAMESPACE_NAME = "marc"; + private static final String NAMESPACE_PREFIX = NAMESPACE_NAME + ":"; + private static final String NAMESPACE_SUFFIX = ":" + NAMESPACE_NAME; - private static final String SUBFIELD_OPEN_TEMPLATE = "<%ssubfield code=\"%s\">"; - private static final String SUBFIELD_CLOSE_TEMPLATE = ""; + 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\""; - private static final String LEADER_TEMPLATE = "<%sleader>%s"; + private static final String ATTRIBUTE_TEMPLATE = " %s=\"%s\""; private static final String NEW_LINE = "\n"; private static final String INDENT = "\t"; @@ -90,7 +105,7 @@ public final class MarcXmlEncoder extends DefaultStreamPipe function, final Object... args) { + final Object[] allArgs = Arrays.copyOf(namespacePrefix, namespacePrefix.length + args.length); + System.arraycopy(args, 0, allArgs, namespacePrefix.length, args.length); + writeRaw(function.apply(allArgs)); + } + private void prettyPrintIndentation() { if (formatted) { final String prefix = String.join("", Collections.nCopies(indentationLevel, INDENT)); diff --git a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java index 566ec13d1..bc6fb0d49 100644 --- a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java +++ b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java @@ -174,9 +174,10 @@ public void issue403_shouldNotEmitNamespaceIfDisabled() { addOneRecord(encoder); addOneRecord(encoder); encoder.closeStream(); - String expected = XML_DECLARATION + String.format(MarcXmlEncoder.ROOT_OPEN_TEMPLATE, "", "", "") + XML_RECORD + XML_RECORD + XML_MARC_COLLECTION_END_TAG; + String expected = XML_DECLARATION + "" + + XML_RECORD + XML_RECORD + XML_MARC_COLLECTION_END_TAG; String actual = resultCollector.toString(); - assertEquals(expected.replace(MarcXmlEncoder.NAMESPACE_PREFIX, ""), actual); + assertEquals(expected.replace("marc:", ""), actual); } @Test(expected = MetafactureException.class)