@Override
  public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
    // This while loop pops all StringBuilders at the top of the stack
    // that contain only whitespace; see GEODE-3306
    while (!stack.empty()) {
      Object o = stack.peek();
      if (o instanceof StringBuilder && StringUtils.isBlank(((StringBuilder) o).toString())) {
        stack.pop();
      } else {
        break;
      }
    }

    try {
      // logger.debug("endElement namespaceURI=" + namespaceURI
      // + "; localName = " + localName + "; qName = " + qName);
      if (qName.equals(CACHE)) {
        endCache();
      } else if (qName.equals(CLIENT_CACHE)) {
        endClientCache();
      } else if (qName.equals(BRIDGE_SERVER)) {
        endCacheServer();
      } else if (qName.equals(CACHE_SERVER)) {
        endCacheServer();
      } else if (qName.equals(LOAD_PROBE)) {
        endLoadProbe();
      } else if (qName.equals(CLIENT_SUBSCRIPTION)) {
        endClientHaQueue();
      } else if (qName.equals(CONNECTION_POOL)) {
        endPool();
      } else if (qName.equals(DYNAMIC_REGION_FACTORY)) {
        endDynamicRegionFactory();
      } else if (qName.equals(GATEWAY_SENDER)) {
        endSerialGatewaySender();
      } else if (qName.equals(GATEWAY_RECEIVER)) {
        endGatewayReceiver();
      } else if (qName.equals(GATEWAY_EVENT_FILTER)) {
        endGatewayEventFilter();
      } else if (qName.equals(GATEWAY_EVENT_SUBSTITUTION_FILTER)) {
        endGatewayEventSubstitutionFilter();
      } else if (qName.equals(GATEWAY_TRANSPORT_FILTER)) {
        endGatewayTransportFilter();
      } else if (qName.equals(ASYNC_EVENT_QUEUE)) {
        endAsyncEventQueue();
      } else if (qName.equals(REGION)) {
        endRegion();
      } else if (qName.equals(GATEWAY_CONFLICT_RESOLVER)) {
        endGatewayConflictResolver();
      } else if (qName.equals(VM_ROOT_REGION)) {
        endRegion();
      } else if (qName.equals(REGION_ATTRIBUTES)) {
        endRegionAttributes();
      } else if (qName.equals(DISK_STORE)) {
        endDiskStore();
      } else if (qName.equals(KEY_CONSTRAINT)) {
        endKeyConstraint();
      } else if (qName.equals(VALUE_CONSTRAINT)) {
        endValueConstraint();
      } else if (qName.equals(REGION_TIME_TO_LIVE)) {
        endRegionTimeToLive();
      } else if (qName.equals(REGION_IDLE_TIME)) {
        endRegionIdleTime();
      } else if (qName.equals(ENTRY_TIME_TO_LIVE)) {
        endEntryTimeToLive();
      } else if (qName.equals(ENTRY_IDLE_TIME)) {
        endEntryIdleTime();
      } else if (qName.equals(CUSTOM_EXPIRY)) {
        endCustomExpiry();
      } else if (qName.equals(DISK_WRITE_ATTRIBUTES)) {
        endDiskWriteAttributes();
      } else if (qName.equals(SYNCHRONOUS_WRITES)) {
      } else if (qName.equals(ASYNCHRONOUS_WRITES)) {
      } else if (qName.equals(DISK_DIRS)) {
        endDiskDirs();
      } else if (qName.equals(DISK_DIR)) {
        endDiskDir();
      } else if (qName.equals(GROUP)) {
        endGroup();
      } else if (qName.equals(PARTITION_ATTRIBUTES)) {
        endPartitionAttributes();
      } else if (qName.equals(FIXED_PARTITION_ATTRIBUTES)) {
        endFixedPartitionAttributes();
      } else if (qName.equals(LOCAL_PROPERTIES)) {
        endPartitionProperites(LOCAL_PROPERTIES);
      } else if (qName.equals(GLOBAL_PROPERTIES)) {
        endPartitionProperites(GLOBAL_PROPERTIES);
      } else if (qName.equals(MEMBERSHIP_ATTRIBUTES)) {
        endMembershipAttributes();
      } else if (qName.equals(REQUIRED_ROLE)) {
        endRequiredRole();
      } else if (qName.equals(EXPIRATION_ATTRIBUTES)) {
      } else if (qName.equals(CUSTOM_EXPIRY)) {
        endCustomExpiry();
      } else if (qName.equals(SUBSCRIPTION_ATTRIBUTES)) {
      } else if (qName.equals(ENTRY)) {
        endEntry();
      } else if (qName.equals(CLASS_NAME)) {
        endClassName();
      } else if (qName.equals(PARAMETER)) {
        endParameter();
      } else if (qName.equals(CACHE_LOADER)) {
        endCacheLoader();
      } else if (qName.equals(CACHE_WRITER)) {
        endCacheWriter();
      } else if (qName.equals(EVICTION_ATTRIBUTES)) {
      } else if (qName.equals(LRU_ENTRY_COUNT)) {
        // internal to eviction-attributes
      } else if (qName.equals(LRU_MEMORY_SIZE)) {
        endLRUMemorySize(); // internal to eviction-attributes
      } else if (qName.equals(LRU_HEAP_PERCENTAGE)) {
        endLRUHeapPercentage(); // internal to eviction-attributes
      } else if (qName.equals(CACHE_LISTENER)) {
        endCacheListener();
      } else if (qName.equals(ASYNC_EVENT_LISTENER)) {
        endAsyncEventListener();
      } else if (qName.equals(KEY)) {
      } else if (qName.equals(VALUE)) {
      } else if (qName.equals(STRING)) {
        endString();
      } else if (qName.equals(DECLARABLE)) {
        endDeclarable();
      } else if (qName.equals(FUNCTIONAL)) {
      } else if (qName.equals(INDEX)) {
        endIndex();
      } else if (qName.equals(PRIMARY_KEY)) {
      } else if (qName.equals(TRANSACTION_MANAGER)) {
        endCacheTransactionManager();
      } else if (qName.equals(TRANSACTION_LISTENER)) {
        endTransactionListener();
      } else if (qName.equals(TRANSACTION_WRITER)) {
        endTransactionWriter();
      } else if (qName.equals(JNDI_BINDINGS)) {
      } else if (qName.equals(JNDI_BINDING)) {
        BindingCreation bc = (BindingCreation) stack.pop();
        Map map = bc.getGFSpecificMap();
        try {
          JNDIInvoker.mapDatasource(map, bc.getVendorSpecificList());
        } catch (NamingException | DataSourceCreateException | ClassNotFoundException | SQLException
            | InstantiationException | IllegalAccessException ex) {
          if (logger.isWarnEnabled()) {
            logger.warn("jndi-binding creation of {} failed with: {}", map.get("jndi-name"), ex);
          }
        }
      } else if (qName.equals(CONFIG_PROPERTY_BINDING)) {
      } else if (qName.equals(CONFIG_PROPERTY_NAME)) {
        String name = null;
        if (stack.peek() instanceof StringBuilder)
        // Pop the config-property-name element value from the stack.
        {
          name = ((StringBuilder) stack.pop()).toString();
        }
        BindingCreation bc = (BindingCreation) stack.peek();
        List vsList = bc.getVendorSpecificList();
        ConfigProperty cp = (ConfigProperty) vsList.get(vsList.size() - 1);
        if (name == null) {
          String excep =
              String.format("Exception in parsing element %s. This is a required field.",
                  qName);
          throw new CacheXmlException(excep);
        } else {
          // set the name.
          cp.setName(name);
        }
      } else if (qName.equals(CONFIG_PROPERTY_VALUE)) {
        String value = null;
        // Pop the config-property-value element value from the stack.
        if (stack.peek() instanceof StringBuilder) {
          value = ((StringBuilder) stack.pop()).toString();
        }
        BindingCreation bc = (BindingCreation) stack.peek();
        List vsList = bc.getVendorSpecificList();
        ConfigProperty cp = (ConfigProperty) vsList.get(vsList.size() - 1);
        // Set the value to the ConfigProperty Data Object.
        cp.setValue(value);
      } else if (qName.equals(CONFIG_PROPERTY_TYPE)) {
        String type = null;
        if (stack.peek() instanceof StringBuilder) {
          type = ((StringBuilder) stack.pop()).toString();
        }
        BindingCreation bc = (BindingCreation) stack.peek();
        List vsList = bc.getVendorSpecificList();
        ConfigProperty cp = (ConfigProperty) vsList.get(vsList.size() - 1);
        if (type == null) {
          String excep =
              String.format("Exception in parsing element %s. This is a required field.",
                  qName);
          throw new CacheXmlException(excep);
        } else {
          cp.setType(type);
        }
      } else if (qName.equals(LRU_MEMORY_SIZE)) { // internal to eviction-attributes
        // Visit startLRUMemorySize() to know the begining
        // of lru-memory-size eviction configuration
        endLRUMemorySize();
      } else if (qName.equals(LOCATOR)) {
        // nothing needed
      } else if (qName.equals(SERVER)) {
        // nothing needed
      } else if (qName.equals(PARTITION_RESOLVER)) {
        endPartitionResolver();
      } else if (qName.equals(PARTITION_LISTENER)) {
        endPartitionListener();
      } else if (qName.equals(FUNCTION)) {
        endFunctionName();
      } else if (qName.equals(FUNCTION_SERVICE)) {
        endFunctionService();
      } else if (qName.equals(TOP_SERIALIZER_REGISTRATION)) {
        endSerializerRegistration();
      } else if (qName.equals(INITIALIZER)) {
        endInitializer();
      } else if (qName.equals(SERIALIZER_REGISTRATION)) {
        endSerializer();
      } else if (qName.equals(INSTANTIATOR_REGISTRATION)) {
        endInstantiator();
      } else if (qName.equals(RESOURCE_MANAGER)) {
        endResourceManager();
      } else if (qName.equals(BACKUP)) {
        endBackup();
      } else if (qName.equals(PDX)) {
        // nothing needed
      } else if (qName.equals(PDX_SERIALIZER)) {
        endPdxSerializer();
      } else if (qName.equals(COMPRESSOR)) {
        endCompressor();
      } else if (qName.equals(SOCKET_FACTORY)) {
        endSocketFactory();
      } else {
        final XmlParser delegate = getDelegate(namespaceURI);
        if (null == delegate) {
          throw new CacheXmlException(
              String.format("Unknown XML element %s", qName));
        }

        delegate.endElement(namespaceURI, localName, qName);
      }
    } catch (CacheException ex) {
      throw new SAXException(
          "A CacheException was thrown while parsing XML.",
          ex);
    }
  }
Add a marker string to look for when in endPartitionProperties

@param localOrGlobal either the string LOCAL_PROPERTIES or GLOBAL_PROPERTIES
geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheXmlParser.java