@@ -60,6 +60,8 @@ public class XMLMatcher extends Matcher {
6060
6161 public static final String DOCUMENT_XML_VERSION_KEY = "document_xml_version" ;
6262
63+ public static final String X_RECHNUNG_KEY = "x_rechnung" ;
64+
6365 public static final int DEFAULT_MAX_ENTITY_EXPANSIONS = 20 ;
6466 private static final String JAXP_ENTITY_EXPANSION_LIMIT_KEY = "jdk.xml.entityExpansionLimit" ;
6567 private static volatile int MAX_ENTITY_EXPANSIONS = determineMaxEntityExpansions ();
@@ -103,6 +105,13 @@ public class XMLMatcher extends Matcher {
103105
104106 private static SoftReference <SAXParserFactory > saxFactoryReference = new SoftReference <>(null );
105107
108+ private static final Map <String , String > X_RECHNUNG_ROOT_ELEMENT_XMLNS_PAIRS ;
109+ static {
110+ X_RECHNUNG_ROOT_ELEMENT_XMLNS_PAIRS = new HashMap <>();
111+ X_RECHNUNG_ROOT_ELEMENT_XMLNS_PAIRS .put ("Invoice" , "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" );
112+ X_RECHNUNG_ROOT_ELEMENT_XMLNS_PAIRS .put ("CrossIndustryInvoice" , "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" );
113+ }
114+
106115 @ Override
107116 public boolean matches (final Context context ) throws IOException {
108117 try {
@@ -121,6 +130,10 @@ public boolean matches(final Context context) throws IOException {
121130 if (handler .getEncoding () != null && !handler .getEncoding ().isEmpty ()) {
122131 mimeType += ";charset=" + handler .getEncoding ();
123132 }
133+ final boolean isXRechnung = matchesXRechnung (handler .getRootElementName (), handler .getNamespaceURI ());
134+ if (isXRechnung ) {
135+ mimeType += ";x-rechnung=true" ;
136+ }
124137
125138 context .setProperty (MimeTypeAction .KEY , mimeType );
126139 context .setProperty (ExtensionAction .KEY , "xml" );
@@ -133,7 +146,10 @@ public boolean matches(final Context context) throws IOException {
133146 // xml version: see
134147 // http://sax.sourceforge.net/apidoc/org/xml/sax/package-summary.html#package_description
135148 putIfPresent (DOCUMENT_XML_VERSION_KEY , handler .getXmlVersion (), xmlDetails );
136-
149+ if (isXRechnung ) {
150+ xmlDetails .put (X_RECHNUNG_KEY , true );
151+ }
152+
137153 // Parser would have thrown a SAXException is this is no proper XML
138154 return true ;
139155 } catch (ParserConfigurationException | SAXException e ) {
@@ -373,4 +389,16 @@ private static int determineMaxEntityExpansions() {
373389 }
374390 return DEFAULT_MAX_ENTITY_EXPANSIONS ;
375391 }
392+
393+ /**
394+ * Returns <code>true</code> if the XML root element and namespace match with those of an X-Rechnung
395+ * standard.
396+ *
397+ * @param rootElement an XML root element
398+ * @param namespaceURI an XML namespace
399+ * @return <code>true</code> if input matches X-Rechnung standard
400+ */
401+ public static boolean matchesXRechnung (String rootElement , String namespaceURI ) {
402+ return X_RECHNUNG_ROOT_ELEMENT_XMLNS_PAIRS .getOrDefault (rootElement , "" ).equals (namespaceURI );
403+ }
376404}
0 commit comments