diff --git a/src/org/openstreetmap/josm/io/XmlWriter.java b/src/org/openstreetmap/josm/io/XmlWriter.java
index 0f06197..ae72868 100644
--- a/src/org/openstreetmap/josm/io/XmlWriter.java
+++ b/src/org/openstreetmap/josm/io/XmlWriter.java
@@ -1,6 +1,8 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
 package org.openstreetmap.josm.io;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+import com.sun.org.apache.xml.internal.utils.XMLChar;
 import java.io.PrintWriter;
 import java.util.HashMap;
 
@@ -38,17 +40,21 @@ public class XmlWriter {
     public static String encode(String unencoded, boolean keepApos) {
         StringBuilder buffer = null;
         for (int i = 0; i < unencoded.length(); ++i) {
+            final char c = unencoded.charAt(i);
             String encS = null;
-            if (!keepApos || unencoded.charAt(i) != '\'') {
-                encS = XmlWriter.encoding.get(unencoded.charAt(i));
+            if (XMLChar.isInvalid(c)) {
+                System.err.println(tr("Skipping invalid XML character U+{0}", Integer.toString(c, 16)));
+                encS = "";
+            } else if (!keepApos || c != '\'') {
+                encS = XmlWriter.encoding.get(c);
             }
             if (encS != null) {
                 if (buffer == null) {
-                    buffer = new StringBuilder(unencoded.substring(0,i));
+                    buffer = new StringBuilder(unencoded.substring(0, i));
                 }
                 buffer.append(encS);
             } else if (buffer != null) {
-                buffer.append(unencoded.charAt(i));
+                buffer.append(c);
             }
         }
         return (buffer == null) ? unencoded : buffer.toString();
