code: public static Element searchForNode(final Element root, final String searchKey, final String attrName,
                                    final DitaClass classValue) {
          if (root == null) {
              return null;
          }
          final Queue<Element> queue = new LinkedList<>();
          queue.offer(root);
          while (!queue.isEmpty()) {
              final Element pe = queue.poll();
              final NodeList pchildrenList = pe.getChildNodes();
              for (int i = 0; i < pchildrenList.getLength(); i++) {
                  final Node node = pchildrenList.item(i);
                  if (node.getNodeType() == Node.ELEMENT_NODE) {
                      queue.offer((Element) node);
                  }
              }
              if (pe.getAttribute(ATTRIBUTE_NAME_CLASS) == null || !classValue.matches(pe)) {
                  continue;
              }
              final Attr value = pe.getAttributeNode(attrName);
              if (value == null) {
                  continue;
              }
              if (searchKey.equals(value.getValue())) {
                  return pe;
              }
          }
          return null;
      }
docs: Search for the special kind of node by specialized value. Equivalent to XPath
  
  <pre>$root//*[contains(@class, $classValue)][@*[name() = $attrName and . = $searchKey]]</pre>
  
  @param root       place may have the node.
  @param searchKey  keyword for search.
  @param attrName   attribute name for search.
  @param classValue class value for search.
  @return matching element, {@code null} if not found