XmlUtil { public static String readUntilEndElementWithDepth(String endElementName, XMLStreamReader reader, XmlEventHandlerWithDepth eventHandler) throws XMLStreamException { Objects.requireNonNull(endElementName); Objects.requireNonNull(reader); String text = null; int event; int depth = 0; while (!((event = reader.next()) == XMLStreamConstants.END_ELEMENT && reader.getLocalName().equals(endElementName))) { text = null; switch (event) { case XMLStreamConstants.START_ELEMENT: if (eventHandler != null) { String startLocalName = reader.getLocalName(); eventHandler.onStartElement(depth); if (reader.getEventType() == XMLStreamConstants.END_ELEMENT && reader.getLocalName().equals(startLocalName)) { depth--; } } depth++; break; case XMLStreamConstants.END_ELEMENT: depth--; break; case XMLStreamConstants.CHARACTERS: text = reader.getText(); break; default: break; } } return text; } private  XmlUtil(); static void readUntilStartElement(String path, XMLStreamReader reader, XmlEventHandler handler); static void readUntilStartElement(String[] elements, XMLStreamReader reader, XmlEventHandler handler); static String readUntilEndElement(String endElementName, XMLStreamReader reader, XmlEventHandler eventHandler); static String readUntilEndElementWithDepth(String endElementName, XMLStreamReader reader, XmlEventHandlerWithDepth eventHandler); static String readText(String endElementName, XMLStreamReader reader); static void writeOptionalBoolean(String name, boolean value, boolean absentValue, XMLStreamWriter writer); static void writeDouble(String name, double value, XMLStreamWriter writer); static void writeOptionalDouble(String name, double value, double absentValue, XMLStreamWriter writer); static void writeFloat(String name, float value, XMLStreamWriter writer); static void writeOptionalFloat(String name, float value, float absentValue, XMLStreamWriter writer); static void writeInt(String name, int value, XMLStreamWriter writer); static void writeOptionalInt(String name, int value, int absentValue, XMLStreamWriter writer); static void writeOptionalString(String name, String value, XMLStreamWriter writer); static int readIntAttribute(XMLStreamReader reader, String attributeName); static boolean readBoolAttribute(XMLStreamReader reader, String attributeName); static boolean readOptionalBoolAttribute(XMLStreamReader reader, String attributeName, boolean defaultValue); static double readDoubleAttribute(XMLStreamReader reader, String attributeName); static double readOptionalDoubleAttribute(XMLStreamReader reader, String attributeName); static double readOptionalDoubleAttribute(XMLStreamReader reader, String attributeName, double defaultValue); static Integer readOptionalIntegerAttribute(XMLStreamReader reader, String attributeName); static int readOptionalIntegerAttribute(XMLStreamReader reader, String attributeName, int defaultValue); static float readFloatAttribute(XMLStreamReader reader, String attributeName); static float readOptionalFloatAttribute(XMLStreamReader reader, String attributeName); static float readOptionalFloatAttribute(XMLStreamReader reader, String attributeName, float defaultValue); static XMLStreamWriter initializeWriter(boolean indent, String indentString, OutputStream os);  }
@Test public void readUntilEndElementWithDepthTest() throws XMLStreamException { Map<String, Integer> depths = new HashMap<>(); try (StringReader reader = new StringReader(XML)) { XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(reader); try { XmlUtil.readUntilEndElementWithDepth("a", xmlReader, elementDepth -> depths.put(xmlReader.getLocalName(), elementDepth)); } finally { xmlReader.close(); } } assertEquals(ImmutableMap.of("a", 0, "b", 1, "c", 2, "d", 1), depths); }