Index: subversion/svnlook/main.c
===================================================================
--- subversion/svnlook/main.c	(revision 31883)
+++ subversion/svnlook/main.c	(working copy)
@@ -43,6 +43,8 @@
 #include "svn_opt.h"
 #include "svn_props.h"
 #include "svn_diff.h"
+#include "svn_xml.h"
+#include "svn_base64.h"
 
 #include "svn_private_config.h"
 
@@ -80,7 +82,8 @@
     svnlook__diff_copy_from,
     svnlook__revprop_opt,
     svnlook__full_paths,
-    svnlook__copy_info
+    svnlook__copy_info,
+    svnlook__xml_opt
   };
 
 /*
@@ -133,6 +136,9 @@
   {"version",           svnlook__version, 0,
    N_("show program version information")},
 
+  {"xml",           svnlook__xml_opt, 0,
+   N_("output in xml")},
+
 #ifndef AS400
   {"extensions",    'x', 1,
                     N_("Default: '-u'. When Subversion is invoking an\n"
@@ -242,7 +248,7 @@
       "List the properties of a path in the repository, or\n"
       "with the --revprop option, revision properties.\n"
       "With -v, show the property values too.\n"),
-   {'r', 't', 'v', svnlook__revprop_opt} },
+   {'r', 't', 'v', svnlook__revprop_opt, svnlook__xml_opt} },
 
   {"tree", subcommand_tree, {0},
    N_("usage: svnlook tree REPOS_PATH [PATH_IN_REPOS]\n\n"
@@ -284,6 +290,7 @@
   svn_boolean_t full_paths;       /* --full-paths */
   svn_boolean_t copy_info;        /* --copy-info */
   svn_boolean_t non_recursive;    /* --non-recursive */
+  svn_boolean_t xml;              /* --xml */
   const char *extensions;         /* diff extension args (UTF-8!) */
 };
 
@@ -1529,6 +1536,47 @@
 }
 
 
+void
+print_xml_prop(svn_stringbuf_t **outstr,
+               const char* propname,
+               svn_string_t *propval,
+               apr_pool_t *pool)
+{
+  const char *xml_safe;
+  const char *encoding = NULL;
+
+  if (*outstr == NULL)
+    *outstr = svn_stringbuf_create("", pool);
+
+  if (svn_xml_is_xml_safe(propval->data, propval->len))
+    {
+      svn_stringbuf_t *xml_esc = NULL;
+      svn_xml_escape_cdata_string(&xml_esc, propval, pool);
+      xml_safe = xml_esc->data;
+    }
+  else
+    {
+      const svn_string_t *base64ed = svn_base64_encode_string(propval, pool);
+      encoding = "base64";
+      xml_safe = base64ed->data;
+    }
+
+  if (encoding)
+    svn_xml_make_open_tag(outstr, pool, svn_xml_protect_pcdata,
+                          "property", "name", propname,
+                          "encoding", encoding, NULL);
+  else
+    svn_xml_make_open_tag(outstr, pool, svn_xml_protect_pcdata,
+                          "property", "name", propname, NULL);
+
+  svn_stringbuf_appendcstr(*outstr, xml_safe);
+
+  svn_xml_make_close_tag(outstr, pool, "property");
+
+  return;
+}
+
+
 /* Print the property names of all properties on PATH in the repository.
    If VERBOSE, print their values too.
    Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist, or with
@@ -1538,6 +1586,7 @@
 do_plist(svnlook_ctxt_t *c,
          const char *path,
          svn_boolean_t verbose,
+         svn_boolean_t xml,
          apr_pool_t *pool)
 {
   svn_stream_t *stdout_stream;
@@ -1545,6 +1594,7 @@
   apr_hash_t *props;
   apr_hash_index_t *hi;
   svn_node_kind_t kind;
+  svn_stringbuf_t *sb = NULL;
 
   SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
   if (path != NULL)
@@ -1556,6 +1606,19 @@
   else
     SVN_ERR(svn_fs_revision_proplist(&props, c->fs, c->rev_id, pool));
 
+  if (xml)
+    {
+      /* <?xml version="1.0"?> */
+      svn_xml_make_header(&sb, pool);
+
+      /* "<properties>" */
+      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties", NULL);
+
+      /* "<target ...>" */
+      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
+                            "path", path, NULL);
+    }
+
   for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
     {
       const void *key;
@@ -1582,12 +1645,36 @@
         {
           const char *pname_stdout;
           SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_stdout, pname, pool));
-          printf("  %s : %s\n", pname_stdout, propval->data);
+          if (xml)
+            print_xml_prop(&sb, pname_stdout, propval, pool);
+          else
+            printf("  %s : %s\n", pname_stdout, propval->data);
         }
       else
-        printf("  %s\n", pname);
+        if (xml)
+          svn_xml_make_open_tag(&sb, pool, svn_xml_self_closing, "property",
+                                "name", pname, NULL);
+        else
+          printf("  %s\n", pname);
     }
+  if (xml)
+    {
+      errno = 0;
+      /* "</target>" */
+      svn_xml_make_close_tag(&sb, pool, "target");
 
+      /* "</properties>" */
+      svn_xml_make_close_tag(&sb, pool, "properties");
+
+      if (fputs(sb->data, stdout) == EOF)
+        {
+          if (errno)
+            return svn_error_wrap_apr(errno, _("Write error"));
+          else
+            return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
+        }
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1904,7 +1991,7 @@
 
   SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
   SVN_ERR(do_plist(c, opt_state->revprop ? NULL : opt_state->arg1,
-                   opt_state->verbose, pool));
+                   opt_state->verbose, opt_state->xml, pool));
   return SVN_NO_ERROR;
 }
 
@@ -2065,6 +2152,10 @@
           opt_state.revprop = TRUE;
           break;
 
+        case svnlook__xml_opt:
+          opt_state.xml = TRUE;
+          break;
+
         case svnlook__version:
           opt_state.version = TRUE;
           break;


