diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 8e727d3fd61281655d112e3f04f3e6369a1165cd..90ea38886824d044136337ebed39d1cd5662b4ba 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -6740,8 +6740,8 @@ namespace Ttcn {
   {
     delete encoding_options;
     delete eb_list;
-    if (NULL != json_printing) {
-      delete json_printing;
+    if (NULL != printing) {
+      delete printing;
     }
   }
 
@@ -7131,7 +7131,7 @@ namespace Ttcn {
             break; }
           
           case ExtensionAttribute::PRINTING: {
-            json_printing = ea.get_printing();
+            printing = ea.get_printing();
             break; }
 
           case ExtensionAttribute::ANYTYPELIST:
@@ -7157,9 +7157,9 @@ namespace Ttcn {
     chk_prototype();
     chk_function_type();
     
-    if (NULL != json_printing && (EXTFUNC_ENCODE != function_type ||
-        Type::CT_JSON != encoding_type)) {
-      error("Attribute 'printing' is only allowed for JSON encoding functions.");
+    if (NULL != printing && (EXTFUNC_ENCODE != function_type ||
+        (Type::CT_JSON != encoding_type && Type::CT_XER != encoding_type))) {
+      error("Attribute 'printing' is only allowed for JSON and XER encoding functions.");
     }
   }
 
@@ -7194,14 +7194,27 @@ namespace Ttcn {
       input_type->get_genname_typedescriptor(my_scope).c_str(),
       Type::get_encoding_name(encoding_type));
     if (encoding_type == Type::CT_JSON) {
-      if (json_printing != NULL) {
-        str = json_printing->generate_code(str);
+      if (printing != NULL) {
+        str = printing->generate_code(str);
       } else {
         str = mputstr(str, ", 0");
       }
+    }  else if (encoding_type == Type::CT_XER) {
+      bool compact_printing =
+        printing != NULL && printing->get_printing() == PrintingType::PT_COMPACT;
+      if (compact_printing || encoding_options) {
+        str = mputstr(str, ", ");
+      }
+      if (compact_printing) {
+        str = mputprintf(str, "XER_CANONICAL%s",
+          encoding_options ? "|" : "");
+      }
+      if (encoding_options) str = mputprintf(str, "%s",
+        encoding_options->c_str());
+    } else {
+      if (encoding_options) str = mputprintf(str, ", %s",
+        encoding_options->c_str());
     }
-    if (encoding_options) str = mputprintf(str, ", %s",
-      encoding_options->c_str());
     str = mputstr(str, ");\n");
     const char *result_name;
     switch (prototype) {
@@ -7599,10 +7612,10 @@ namespace Ttcn {
       }
       
       // insert printing type
-      if (json_printing != NULL) {
+      if (printing != NULL) {
         json->put_next_token(JSON_TOKEN_NAME, "printing");
         json->put_next_token(JSON_TOKEN_STRING, 
-          (json_printing->get_printing() == PrintingType::PT_PRETTY) ? 
+          (printing->get_printing() == PrintingType::PT_PRETTY) ? 
           "\"pretty\"" : "\"compact\"");
       }
       
diff --git a/compiler2/ttcn3/AST_ttcn3.hh b/compiler2/ttcn3/AST_ttcn3.hh
index aeb433e38e3d2f96bcb252eace664d4096db01ad..cfadc7a670cd48a2769c89ed92cf7377bb43f23e 100644
--- a/compiler2/ttcn3/AST_ttcn3.hh
+++ b/compiler2/ttcn3/AST_ttcn3.hh
@@ -1537,7 +1537,8 @@ namespace Ttcn {
     Type::MessageEncodingType_t encoding_type;
     string *encoding_options;
     Ttcn::ErrorBehaviorList *eb_list;
-    Ttcn::PrintingType *json_printing;
+    // pretty or compact printing for json or xml
+    Ttcn::PrintingType *printing;
     /// Copy constructor disabled
     Def_ExtFunction(const Def_ExtFunction& p);
     /// %Assignment disabled
@@ -1559,7 +1560,7 @@ namespace Ttcn {
       : Def_Function_Base(true, p_id, p_fpl, p_return_type, returns_template,
           p_template_restriction),
       function_type(EXTFUNC_MANUAL), encoding_type(Type::CT_UNDEF),
-      encoding_options(0), eb_list(0), json_printing(0) { }
+      encoding_options(0), eb_list(0), printing(0) { }
     ~Def_ExtFunction();
     virtual Def_ExtFunction *clone() const;
     virtual void set_fullname(const string& p_fullname);
diff --git a/core/Basetype.cc b/core/Basetype.cc
index 3d1386ae8ad27783b9955886b93f33d71fe960d5..8e2d53ff0ec48e9730877dc32aca75c2a480325d 100644
--- a/core/Basetype.cc
+++ b/core/Basetype.cc
@@ -217,6 +217,7 @@ void Base_Type::XER_encode_chk_coding(unsigned& p_coding,
   }
   switch (p_coding) {
   case XER_BASIC:
+  case XER_BASIC | XER_CANONICAL:
   case XER_CANONICAL:
   case XER_EXTENDED:
   case XER_EXTENDED | XER_CANONICAL:
diff --git a/regression_test/XML/Makefile b/regression_test/XML/Makefile
index f2506c080c5b34897e3d7b485cbf82ddba94807a..60583cf3b1a63a3a2979520dc3ba971d14b9daa9 100644
--- a/regression_test/XML/Makefile
+++ b/regression_test/XML/Makefile
@@ -30,7 +30,7 @@ endif
 XDIRS := $(wildcard $(SHADOWED)) xsdConverter \
 HM60295 HN15589 HQ30408 HR49727 HU13380 $(RT2_ONLY) \
 XmlWorkflow tpdValidTest AbstractBlock UseNilLong AttributeFormDefault \
-RecordOmit XSDBaseType LegacyUntaggedUnion
+RecordOmit XSDBaseType LegacyUntaggedUnion Printing
 
 # List of fake targets:
 .PHONY: all dep clean run $(XDIRS) $(addsuffix /, $(XDIRS)) profile
diff --git a/regression_test/XML/Printing/.gitignore b/regression_test/XML/Printing/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..700a8c171f7a105e4ab92e240230b8193df13ec0
--- /dev/null
+++ b/regression_test/XML/Printing/.gitignore
@@ -0,0 +1,8 @@
+*.old
+*.log
+compile
+*.cc
+*.hh
+*.d
+Printing
+Printing.exe
\ No newline at end of file
diff --git a/regression_test/XML/Printing/Makefile b/regression_test/XML/Printing/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c49ae283adb0134dce76f5e9fae500ff7a9efecd
--- /dev/null
+++ b/regression_test/XML/Printing/Makefile
@@ -0,0 +1,147 @@
+##############################################################################
+# Copyright (c) 2000-2017 Ericsson Telecom AB
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#   Bence Janos Szabo – initial implementation
+#
+##############################################################################
+TOPDIR = ../..
+include  ../../Makefile.regression
+
+# WARNING! This Makefile can be used with GNU make only.
+# Other versions of make may report syntax errors in it.
+
+#
+# Do NOT touch this line...
+#
+.PHONY: all archive check clean dep objects
+
+.SUFFIXES: .d
+
+#
+# Set these variables...
+#
+
+# Flags for the C++ preprocessor (and makedepend as well):
+#CPPFLAGS +=
+
+# Flags for dependency generation
+CXXDEPFLAGS = -MM
+
+# Flags for the C++ compiler:
+CXXFLAGS += -Wall
+
+# Flags for the linker:
+#LDFLAGS += 
+
+# Flags for the TTCN-3 and ASN.1 compiler:
+#COMPILER_FLAGS +=  
+
+# Execution mode: (either ttcn3 or ttcn3-parallel)
+TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
+
+#
+# You may change these variables. Add your files if necessary...
+#
+
+# TTCN-3 modules of this project:
+TTCN3_MODULES = Printing.ttcn
+
+# ASN.1 modules of this project:
+ASN1_MODULES =
+
+# C++ source & header files generated from the TTCN-3 & ASN.1 modules of
+# this project:
+GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc)
+GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
+ifdef SPLIT_TO_SLICES
+POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
+POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
+GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
+GENERATED_SOURCES += $(GENERATED_SOURCES2)
+endif
+# C/C++ Source & header files of Test Ports, external functions and
+# other modules:
+USER_SOURCES =
+USER_HEADERS = $(USER_SOURCES:.cc=.hh)
+
+# Object files of this project that are needed for the executable test suite:
+OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)
+
+GENERATED_OBJECTS = $(GENERATED_SOURCES:.cc=.o)
+
+USER_OBJECTS = $(USER_SOURCES:.cc=.o)
+
+DEPFILES = $(USER_OBJECTS:.o=.d)  $(GENERATED_OBJECTS:.o=.d)
+
+# Other files of the project (Makefile, configuration files, etc.)
+# that will be added to the archived source files:
+OTHER_FILES = Makefile
+
+# The name of the executable test suite:
+TARGET = UseNilLong
+
+#
+# Rules for building the executable...
+#
+
+all: $(TARGET) ;
+
+objects: $(OBJECTS) compile;
+
+$(TARGET): $(OBJECTS)
+	if $(CXX) $(LDFLAGS) -o $@ $^ \
+	-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
+	-L$(OPENSSL_DIR)/lib -lcrypto \
+	-L$(XMLDIR)/lib $($(PLATFORM)_LIBS); \
+	then : ; else $(TTCN3_DIR)/bin/titanver $(OBJECTS); exit 1; fi
+
+.cc.o .c.o:
+	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
+
+.cc.d .c.d:
+	@echo Creating dependency file for '$<'; set -e; \
+	$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
+	| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+	[ -s $@ ] || rm -f $@
+
+$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile
+	@if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi
+
+compile: $(TTCN3_MODULES) $(ASN1_MODULES)
+	$(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ - $?
+	touch $@
+
+clean distclean:
+	-$(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
+	$(GENERATED_SOURCES) compile $(DEPFILES) \
+	tags *.log
+
+dep: $(GENERATED_SOURCES) $(USER_SOURCES) ;
+
+ifeq ($(findstring n,$(MAKEFLAGS)),)
+ifeq ($(filter clean distclean check compile archive diag,$(MAKECMDGOALS)),)
+-include $(DEPFILES)
+endif
+endif
+
+diag:
+	$(TTCN3_COMPILER) -v 2>&1
+	$(TTCN3_DIR)/bin/mctr_cli -v 2>&1
+	$(CXX) -v 2>&1
+	@echo TTCN3_DIR=$(TTCN3_DIR)
+	@echo OPENSSL_DIR=$(OPENSSL_DIR)
+	@echo XMLDIR=$(XMLDIR)
+	@echo PLATFORM=$(PLATFORM)
+
+#
+# Add your rules here if necessary...
+#
+
+run: $(TARGET)
+	./$^
+
diff --git a/regression_test/XML/Printing/Printing.ttcn b/regression_test/XML/Printing/Printing.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..e931a4620c9e85d8cd336179f886c624bc9ae188
--- /dev/null
+++ b/regression_test/XML/Printing/Printing.ttcn
@@ -0,0 +1,202 @@
+/******************************************************************************
+ * Copyright (c) 2000-2017 Ericsson Telecom AB
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Szabo, Bence Janos
+ *
+ ******************************************************************************/
+module Printing {
+
+
+	type component EmptyCT {
+
+	}
+
+	type union MyUnion {
+		integer i
+	}
+
+	type record of MyRec MyRecOf;
+
+	type record MyRec {
+		MyRecOf recof optional,
+		MyUnion un optional,
+		integer i optional
+	}
+
+
+	external function enc_compact0(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER) printing(compact)" }
+
+	external function enc_compact1(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_EXTENDED) printing(compact)" }
+
+	external function enc_compact2(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_BASIC) printing(compact)" }
+
+	external function enc_compact3(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_EXTENDED|XER_CANONICAL) printing(compact)" } // !!!
+
+
+	external function enc_pretty0(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER)" }
+
+	external function enc_pretty1(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_BASIC)" }
+
+	external function enc_pretty2(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_EXTENDED)" }
+
+	external function enc_pretty3(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER) printing(pretty)" }
+
+	external function enc_pretty4(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_EXTENDED) printing(pretty)" }
+
+	external function enc_pretty5(in MyRec a) return octetstring
+	 with { extension "prototype(convert) encode(XER:XER_BASIC) printing(pretty)" }
+
+
+	external function dec_basic(in octetstring a) return MyRec
+	 with { extension "prototype(convert) decode(XER:XER_BASIC)" }
+
+
+const MyRec c_myrec := { recof := {{recof := omit, un := {i := 1}, i := 3}, {recof := omit, un := omit, i := 4}}, un := { i := 4}, i := 5};
+const universal charstring c_compact :=
+"<MyRec>"&
+	"<recof>"&
+		"<MyRec>"&
+			"<un>"&
+				"<i>1</i>"&
+			"</un>"&
+			"<i>3</i>"&
+		"</MyRec>"&
+		"<MyRec>"&
+			"<i>4</i>"&
+		"</MyRec>"&
+	"</recof>"&
+	"<un>"&
+		"<i>4</i>"&
+	"</un>"&
+	"<i>5</i>"&
+"</MyRec>\n";
+
+const universal charstring c_pretty :=
+"<MyRec>\n"&
+"\t<recof>\n"&
+"\t\t<MyRec>\n"&
+"\t\t\t<un>\n"&
+"\t\t\t\t<i>1</i>\n"&
+"\t\t\t</un>\n"&
+"\t\t\t<i>3</i>\n"&
+"\t\t</MyRec>\n"&
+"\t\t<MyRec>\n"&
+"\t\t\t<i>4</i>\n"&
+"\t\t</MyRec>\n"&
+"\t</recof>\n"&
+"\t<un>\n"&
+"\t\t<i>4</i>\n"&
+"\t</un>\n"&
+"\t<i>5</i>\n"&
+"</MyRec>\n\n"
+
+
+testcase tc_compact() runs on EmptyCT {
+	var octetstring os;
+	var MyRec myrec;
+
+	os := enc_compact0(c_myrec);
+	if (oct2unichar(os) != c_compact) {
+		setverdict(fail, match(oct2unichar(os), c_compact));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_compact1(c_myrec);
+	if (oct2unichar(os) != c_compact) {
+		setverdict(fail, match(oct2unichar(os), c_compact));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_compact2(c_myrec);
+	if (oct2unichar(os) != c_compact) {
+		setverdict(fail, match(oct2unichar(os), c_compact));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_compact3(c_myrec);
+	if (oct2unichar(os) != c_compact) {
+		setverdict(fail, match(oct2unichar(os), c_compact));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	setverdict(pass);
+}
+
+testcase tc_pretty() runs on EmptyCT {
+	var octetstring os;
+	var MyRec myrec;
+
+	os := enc_pretty0(c_myrec);
+	if (oct2unichar(os) != c_pretty) {
+		setverdict(fail, match(oct2unichar(os), c_pretty));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_pretty1(c_myrec);
+	if (oct2unichar(os) != c_pretty) {
+		setverdict(fail, match(oct2unichar(os), c_pretty));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_pretty2(c_myrec);
+	if (oct2unichar(os) != c_pretty) {
+		setverdict(fail, match(oct2unichar(os), c_pretty));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	os := enc_pretty3(c_myrec);
+	if (oct2unichar(os) != c_pretty) {
+		setverdict(fail, match(oct2unichar(os), c_pretty));
+	}
+	myrec := dec_basic(os);
+	if (myrec != c_myrec) {
+		setverdict(fail, match(myrec, c_myrec));
+	}
+
+	setverdict(pass);
+}
+
+control {
+	execute(tc_compact());
+	execute(tc_pretty());
+}
+
+}
+with {
+  encode "XML";
+}
diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc
index 2d0a4de28daee726c4c5ca3f1af1abb983fac98f..2b6744feeb90866970859a5a5e0132cf0aa5d5b8 100644
Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ