Index: /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 13429)
+++ /trunk/src/org/openstreetmap/josm/data/osm/Tagged.java	(revision 13430)
@@ -76,11 +76,26 @@
     /**
      * Replies true if there is a tag with key <code>key</code>.
+     * The value could however be empty. See {@link #hasTag(String)} to check for non-empty tags.
      *
      * @param key the key
      * @return true, if there is a tag with key <code>key</code>
+     * @see #hasTag(String)
      * @since 11608
      */
     default boolean hasKey(String key) {
         return get(key) != null;
+    }
+
+    /**
+     * Replies true if there is a non-empty tag with key <code>key</code>.
+     *
+     * @param key the key
+     * @return true, if there is a non-empty tag with key <code>key</code>
+     * @see Tagged#hasKey(String)
+     * @since 13430
+     */
+    default boolean hasTag(String key) {
+        String v = get(key);
+        return v != null && !v.isEmpty();
     }
 
Index: /trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 13429)
+++ /trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 13430)
@@ -836,9 +836,9 @@
                 return false;
             case MISSING_KEY:
-                return osm.get(key) == null;
+                return !osm.hasTag(key);
             case ANY:
                 return true;
             case ANY_VALUE:
-                return osm.get(key) != null;
+                return osm.hasTag(key);
             case ANY_KEY:
                 for (String v:osm.getKeys().values()) {
Index: /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java	(revision 13429)
+++ /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java	(revision 13430)
@@ -496,4 +496,16 @@
 
     /**
+     * Test empty values.
+     * @throws SearchParseError never
+     */
+    @Test
+    public void testEmptyValues15943() throws SearchParseError {
+        Match matcher = SearchCompiler.compile("access=");
+        assertTrue(matcher.match(new Tag("access", null)));
+        assertTrue(matcher.match(new Tag("access", "")));
+        assertFalse(matcher.match(new Tag("access", "private")));
+    }
+
+    /**
      * Unit test of {@link SearchCompiler.ExactKeyValue.Mode} enum.
      */
@@ -562,5 +574,4 @@
     }
 
-
     /**
      * Ensures that correct presets are stored in the {@link org.openstreetmap.josm.data.osm.search.SearchCompiler.Preset}
