@@ -61,7 +61,7 @@ public class XmlSchemaParser
6161 "/*[local-name() = 'messageSchema']" ;
6262
6363 static final String MESSAGE_XPATH_EXPR =
64- "//*[local-name() = 'message']" ;
64+ "/*[local-name() = 'messageSchema'] /*[local-name() = 'message']" ;
6565
6666 /**
6767 * Validate the document against a given schema. Errors will be written to {@link java.lang.System#err}.
@@ -141,6 +141,11 @@ public static MessageSchema parse(final InputSource is, final ParserOptions opti
141141 errorHandler .checkIfShouldExit ();
142142
143143 final Node schemaNode = (Node )xPath .compile (MESSAGE_SCHEMA_XPATH_EXPR ).evaluate (document , XPathConstants .NODE );
144+ if (null == schemaNode )
145+ {
146+ throw new IllegalStateException ("messageSchema element not found in document, schema is not valid for SBE" );
147+ }
148+
144149 final MessageSchema messageSchema = new MessageSchema (schemaNode , typeByNameMap , messageByIdMap );
145150 errorHandler .checkIfShouldExit ();
146151
@@ -167,9 +172,9 @@ public static MessageSchema parse(final InputStream in, final ParserOptions opti
167172 /**
168173 * Scan XML for all types (encodedDataType, compositeType, enumType, and setType) and save in map.
169174 *
170- * @param document for the XML parsing
171- * @param xPath for XPath expression reuse
172- * @return {@link java.util.Map} of name {@link java.lang.String} to Type
175+ * @param document for the XML parsing.
176+ * @param xPath for XPath expression reuse.
177+ * @return {@link java.util.Map} of name {@link java.lang.String} to {@link Type}.
173178 * @throws Exception on parsing error.
174179 */
175180 public static Map <String , Type > findTypes (final Document document , final XPath xPath ) throws Exception
@@ -206,10 +211,10 @@ public static Map<String, Type> findTypes(final Document document, final XPath x
206211 /**
207212 * Scan XML for all message definitions and save in map.
208213 *
209- * @param document for the XML parsing
210- * @param xPath for XPath expression reuse
211- * @param typeByNameMap to use for Type objects
212- * @return {@link java.util.Map} of schemaId to Message
214+ * @param document for the XML parsing.
215+ * @param xPath for XPath expression reuse.
216+ * @param typeByNameMap to use for Type objects.
217+ * @return {@link java.util.Map} of schemaId to {@link Message}.
213218 * @throws Exception on parsing error.
214219 */
215220 public static Map <Long , Message > findMessages (
@@ -221,6 +226,11 @@ public static Map<Long, Message> findMessages(
221226 forEach ((NodeList )xPath .compile (MESSAGE_XPATH_EXPR ).evaluate (document , XPathConstants .NODESET ),
222227 (node ) -> addMessageWithIdCheck (distinctNames , messageByIdMap , new Message (node , typeByNameMap ), node ));
223228
229+ if (messageByIdMap .isEmpty ())
230+ {
231+ handleWarning (document .getDocumentElement (), "no messages found in document" );
232+ }
233+
224234 return messageByIdMap ;
225235 }
226236
@@ -233,8 +243,7 @@ public static Map<Long, Message> findMessages(
233243 public static void handleError (final Node node , final String msg )
234244 {
235245 final ErrorHandler handler = (ErrorHandler )node .getOwnerDocument ().getUserData (ERROR_HANDLER_KEY );
236-
237- if (handler == null )
246+ if (null == handler )
238247 {
239248 throw new IllegalStateException ("ERROR: " + formatLocationInfo (node ) + msg );
240249 }
@@ -253,8 +262,7 @@ public static void handleError(final Node node, final String msg)
253262 public static void handleWarning (final Node node , final String msg )
254263 {
255264 final ErrorHandler handler = (ErrorHandler )node .getOwnerDocument ().getUserData (ERROR_HANDLER_KEY );
256-
257- if (handler == null )
265+ if (null == handler )
258266 {
259267 throw new IllegalStateException ("WARNING: " + formatLocationInfo (node ) + msg );
260268 }
@@ -267,13 +275,19 @@ public static void handleWarning(final Node node, final String msg)
267275 /**
268276 * Helper function that throws an exception when the attribute is not set.
269277 *
270- * @param elementNode that should have the attribute
271- * @param attrName that is to be looked up
272- * @return value of the attribute
273- * @throws IllegalArgumentException if the attribute is not present
278+ * @param elementNode that should have the attribute.
279+ * @param attrName that is to be looked up.
280+ * @return value of the attribute.
281+ * @throws IllegalStateException if the attribute is not present.
274282 */
275283 public static String getAttributeValue (final Node elementNode , final String attrName )
276284 {
285+ if (null == elementNode )
286+ {
287+ throw new IllegalStateException (
288+ "element node is null when looking for attribute: " + attrName );
289+ }
290+
277291 final NamedNodeMap attributes = elementNode .getAttributes ();
278292 if (null == attributes )
279293 {
@@ -282,7 +296,7 @@ public static String getAttributeValue(final Node elementNode, final String attr
282296 }
283297
284298 final Node attrNode = attributes .getNamedItemNS (null , attrName );
285- if (attrNode == null || "" .equals (attrNode .getNodeValue ()))
299+ if (null == attrNode || "" .equals (attrNode .getNodeValue ()))
286300 {
287301 throw new IllegalStateException (
288302 "element '" + elementNode .getNodeName () + "' has empty or missing attribute: " + attrName );
@@ -294,22 +308,27 @@ public static String getAttributeValue(final Node elementNode, final String attr
294308 /**
295309 * Helper function that uses a default value when value not set.
296310 *
297- * @param elementNode that should have the attribute
298- * @param attrName that is to be looked up
299- * @param defValue String to return if not set
300- * @return value of the attribute or defValue
311+ * @param elementNode that should have the attribute.
312+ * @param attrName that is to be looked up.
313+ * @param defValue value to return if not set.
314+ * @return value of the attribute or defValue.
301315 */
302316 public static String getAttributeValue (final Node elementNode , final String attrName , final String defValue )
303317 {
318+ if (null == elementNode )
319+ {
320+ throw new IllegalStateException (
321+ "element node is null when looking for attribute: " + attrName );
322+ }
323+
304324 final NamedNodeMap attributes = elementNode .getAttributes ();
305- if (attributes == null )
325+ if (null == attributes )
306326 {
307327 return defValue ;
308328 }
309329
310330 final Node attrNode = attributes .getNamedItemNS (null , attrName );
311-
312- if (attrNode == null )
331+ if (null == attrNode )
313332 {
314333 return defValue ;
315334 }
@@ -320,9 +339,9 @@ public static String getAttributeValue(final Node elementNode, final String attr
320339 /**
321340 * Helper function that hides the null return from {@link org.w3c.dom.NamedNodeMap#getNamedItem(String)}.
322341 *
323- * @param elementNode that could be null
324- * @param attrName that is to be looked up
325- * @return null or value of the attribute
342+ * @param elementNode that could be null.
343+ * @param attrName that is to be looked up.
344+ * @return null or value of the attribute.
326345 */
327346 public static String getAttributeValueOrNull (final Node elementNode , final String attrName )
328347 {
@@ -343,8 +362,8 @@ public static String getAttributeValueOrNull(final Node elementNode, final Strin
343362 /**
344363 * Helper function to convert a schema byteOrderName into a {@link ByteOrder}.
345364 *
346- * @param byteOrderName specified as a FIX SBE string
347- * @return ByteOrder representation
365+ * @param byteOrderName specified as a FIX SBE string.
366+ * @return ByteOrder representation.
348367 */
349368 public static ByteOrder getByteOrder (final String byteOrderName )
350369 {
0 commit comments