diff --git a/README.md b/README.md
index faf4cb9..49b8761 100644
--- a/README.md
+++ b/README.md
@@ -165,6 +165,9 @@ TagLib
| encoder-jakarta-jsp | <%@taglib prefix="e" uri="owasp.encoder.jakarta"%> |
| encoder-jsp | <%@taglib prefix="e" uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project"%> |
+Every `Encode.forX(String)` context has a tag and an EL function in the advanced
+taglib, except `forJava`: Java source generation is not a JSP output context.
+
Migrating from forUri
---------------------
@@ -225,6 +228,7 @@ Development builds use `1.5.0-SNAPSHOT`; this is not a published release.
* feat: all four `forJavaScript*` methods encode dollar sign (`$`) as `\x24`, backtick as `\x60`, and opening brace (`{`) as `\x7b` [#129](https://github.com/OWASP/owasp-java-encoder/issues/129). Escaping `{` prevents input after a trusted `$` from completing `${...}`. Encoded output now supports literal text in ordinary (untagged) template literals as well as single- and double-quoted strings. This changes the encoded output while preserving its decoded JavaScript string value. Tagged templates (including `String.raw`), `${...}` expression bodies, JSON, and script URLs are unsupported; each method's HTML context restrictions still apply.
* fix: all four `forJavaScript*` methods escape unpaired UTF-16 surrogates as `\uXXXX`, preserving their JavaScript string values through UTF-8 serialization [#135](https://github.com/OWASP/owasp-java-encoder/issues/135), and escape DEL/C1 controls (U+007F to U+009F) as `\xNN` [#163](https://github.com/OWASP/owasp-java-encoder/issues/163). Valid surrogate pairs and other non-ASCII text remain unescaped except U+2028/U+2029. These are output-fidelity changes; NEL was already ordinary JavaScript string data.
* feat: add `Encode.forJson` String/Writer methods, the `json` encoder context, and `forJson` tags and EL functions in both JSP and Jakarta tag libraries [#145](https://github.com/OWASP/owasp-java-encoder/issues/145). The caller supplies double quotes. Output uses RFC 8259 string escapes and also escapes HTML script delimiters. Java `null` becomes the text `null` (the JSON string `"null"` when quoted); unpaired surrogates use Unicode escapes and may not interoperate with every JSON consumer. Prefer a serializer for complete JSON documents. The ESAPI adapter retains its existing JSON delegation and null behavior.
+* feat: add `forXml11`, `forXml11Content` and `forXml11Attribute` tags and EL functions to the advanced JSP and Jakarta taglibs, and `forXml11` to the basic taglibs [#131](https://github.com/OWASP/owasp-java-encoder/issues/131).
* deprecation: `Encoders.URI` and both `ForUriTag` classes are now deprecated like `Encode.forUri`, whose Javadoc now says what to use instead; the `forUri` TLD descriptions warn about double encoding, the adapter builds show deprecation call sites, and the README has a [forUri migration section](#migrating-from-foruri) [#130](https://github.com/OWASP/owasp-java-encoder/issues/130).
* fix: the JSP, Jakarta and ESAPI bundles now declare the core versions they need (`[1.5,2)` for the tags, which call `Encode.forJson`; `[1.4.1,2)` for ESAPI) and the JSP API ranges they support, instead of unversioned imports that could wire to an older core and fail when a tag ran. Bundle symbolic names are now declared explicitly and unchanged [#137](https://github.com/OWASP/owasp-java-encoder/issues/137).
* fix: `forHtmlUnquotedAttribute` now replaces U+0085 (NEL) with a hyphen like the other C1 control characters, instead of emitting `
`, which HTML5 parsers decode as U+2026 [#136](https://github.com/OWASP/owasp-java-encoder/issues/136).
diff --git a/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java
new file mode 100644
index 0000000..bd93b63
--- /dev/null
+++ b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import jakarta.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Attribute Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11Attribute(java.lang.String)}.
+ */
+public class ForXml11AttributeTag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11Attribute(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java
new file mode 100644
index 0000000..dba7058
--- /dev/null
+++ b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import jakarta.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Content Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11Content(java.lang.String)}.
+ */
+public class ForXml11ContentTag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11Content(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java
new file mode 100644
index 0000000..7ad54ea
--- /dev/null
+++ b/jakarta/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import jakarta.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11(java.lang.String)}.
+ */
+public class ForXml11Tag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jakarta/src/main/resources/META-INF/java-encoder-advanced.tld b/jakarta/src/main/resources/META-INF/java-encoder-advanced.tld
index 0480e14..b40b586 100644
--- a/jakarta/src/main/resources/META-INF/java-encoder-advanced.tld
+++ b/jakarta/src/main/resources/META-INF/java-encoder-advanced.tld
@@ -56,6 +56,23 @@
java.lang.String
+
+
+ Encodes for XML 1.1 attribute content. Encodes control characters the same way
+ as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Attribute
+ forXml11Attribute
+ org.owasp.encoder.tag.ForXml11AttributeTag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes for XML and XHTML.
forXml
@@ -70,6 +87,27 @@
java.lang.String
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.tag.ForXml11Tag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script
@@ -350,6 +388,24 @@
java.lang.String
+
+
+ Encodes XML 1.1 text content. Does not escape quotes and is unsafe for attribute
+ values; use forXml11 or forXml11Attribute for those contexts. Encodes control
+ characters the same way as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Content
+ forXml11Content
+ org.owasp.encoder.tag.ForXml11ContentTag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Performs percent-encoding for a component of a URI, such as a query
@@ -498,6 +554,21 @@
java.lang.String forXml(java.lang.String)
forXml(unsafeData)
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.Encode
+ java.lang.String forXml11(java.lang.String)
+ forXml11(unsafeData)
+
Encodes XML and XHTML text content. Does not escape quotes and is unsafe for attribute values; use forXml or forXmlAttribute for those contexts.
@@ -508,6 +579,18 @@
java.lang.String forXmlContent(java.lang.String)
forXmlContent(unsafeData)
+
+
+ Encodes XML 1.1 text content. Does not escape quotes and is unsafe for attribute
+ values; use forXml11 or forXml11Attribute for those contexts. Encodes control
+ characters the same way as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Content
+ forXml11Content
+ org.owasp.encoder.Encode
+ java.lang.String forXml11Content(java.lang.String)
+ forXml11Content(unsafeData)
+
Encodes for XML and XHTML attribute content.
forXmlAttribute
@@ -516,6 +599,17 @@
java.lang.String forXmlAttribute(java.lang.String)
forXmlAttribute(unsafeData)
+
+
+ Encodes for XML 1.1 attribute content. Encodes control characters the same way
+ as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Attribute
+ forXml11Attribute
+ org.owasp.encoder.Encode
+ java.lang.String forXml11Attribute(java.lang.String)
+ forXml11Attribute(unsafeData)
+
Encoder for XML comments. NOT FOR USE WITH (X)HTML CONTEXTS.
diff --git a/jakarta/src/main/resources/META-INF/java-encoder.tld b/jakarta/src/main/resources/META-INF/java-encoder.tld
index a4c56d9..621bfbd 100644
--- a/jakarta/src/main/resources/META-INF/java-encoder.tld
+++ b/jakarta/src/main/resources/META-INF/java-encoder.tld
@@ -73,6 +73,27 @@
java.lang.String
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.tag.ForXml11Tag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script
@@ -393,6 +414,21 @@
java.lang.String forXml(java.lang.String)
forXml(unsafeData)
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.Encode
+ java.lang.String forXml11(java.lang.String)
+ forXml11(unsafeData)
+
Encodes XML and XHTML text content. Does not escape quotes and is unsafe for attribute values; use forXml or forXmlAttribute for those contexts.
diff --git a/jakarta/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java b/jakarta/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
index 9fa7664..2c08222 100644
--- a/jakarta/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
+++ b/jakarta/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
@@ -105,13 +105,13 @@ static Taglib load(String resource) throws Exception {
}
/**
- * Java source generation is not a JSP context. XML 1.1 tags are tracked
- * separately in issue #131. Deprecated forUri remains for compatibility;
- * deprecation alone must not silently remove a deployed tag/function.
+ * Java source generation is not a JSP context, so forJava is the only
+ * facade method without a tag and function. Deprecated forUri remains for
+ * compatibility; deprecation alone must not silently remove a deployed
+ * tag/function.
*/
public void testAdvancedMatchesSupportedFacade() throws Exception {
- Set unsupported = new TreeSet(Arrays.asList(
- "forJava", "forXml11", "forXml11Content", "forXml11Attribute"));
+ Set unsupported = new TreeSet(Arrays.asList("forJava"));
Set expected = new TreeSet();
for (Method method : Encode.class.getMethods()) {
if (Modifier.isStatic(method.getModifiers()) && method.getName().startsWith("for")
@@ -214,7 +214,7 @@ public void testBasicIsSubsetOfAdvanced() throws Exception {
Set expectedBasic = new TreeSet(Arrays.asList(
"forCDATA", "forCssString", "forCssUrl", "forHtml", "forHtmlAttribute",
"forHtmlContent", "forHtmlUnquotedAttribute", "forJavaScript", "forJson",
- "forUri", "forUriComponent", "forXml", "forXmlAttribute", "forXmlContent"));
+ "forUri", "forUriComponent", "forXml", "forXml11", "forXmlAttribute", "forXmlContent"));
assertEquals("basic tags", expectedBasic, basic.tagClasses.keySet());
assertEquals("basic functions", expectedBasic, basic.functionSignatures.keySet());
for (Map.Entry tag : basic.tagClasses.entrySet()) {
diff --git a/jsp/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java
new file mode 100644
index 0000000..0a87d68
--- /dev/null
+++ b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11AttributeTag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import javax.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Attribute Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11Attribute(java.lang.String)}.
+ */
+public class ForXml11AttributeTag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11Attribute(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jsp/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java
new file mode 100644
index 0000000..8c0d859
--- /dev/null
+++ b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11ContentTag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import javax.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Content Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11Content(java.lang.String)}.
+ */
+public class ForXml11ContentTag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11Content(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jsp/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java
new file mode 100644
index 0000000..d8572e5
--- /dev/null
+++ b/jsp/src/main/java/org/owasp/encoder/tag/ForXml11Tag.java
@@ -0,0 +1,50 @@
+// Copyright (c) 2026 OWASP
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the following
+// disclaimer.
+//
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials
+// provided with the distribution.
+//
+// * Neither the name of the OWASP nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+// OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package org.owasp.encoder.tag;
+
+import java.io.IOException;
+import javax.servlet.jsp.JspException;
+import org.owasp.encoder.Encode;
+
+/**
+ * A tag to perform XML 1.1 Encoding.
+ * This wraps the {@link org.owasp.encoder.Encode#forXml11(java.lang.String)}.
+ */
+public class ForXml11Tag extends EncodingTag {
+ @Override
+ public void doTag() throws JspException, IOException {
+ Encode.forXml11(getJspContext().getOut(), _value);
+ }
+}
diff --git a/jsp/src/main/resources/META-INF/java-encoder-advanced.tld b/jsp/src/main/resources/META-INF/java-encoder-advanced.tld
index 5217a86..6ec5ed3 100644
--- a/jsp/src/main/resources/META-INF/java-encoder-advanced.tld
+++ b/jsp/src/main/resources/META-INF/java-encoder-advanced.tld
@@ -56,6 +56,23 @@
java.lang.String
+
+
+ Encodes for XML 1.1 attribute content. Encodes control characters the same way
+ as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Attribute
+ forXml11Attribute
+ org.owasp.encoder.tag.ForXml11AttributeTag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes for XML and XHTML.
forXml
@@ -70,6 +87,27 @@
java.lang.String
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.tag.ForXml11Tag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script
@@ -350,6 +388,24 @@
java.lang.String
+
+
+ Encodes XML 1.1 text content. Does not escape quotes and is unsafe for attribute
+ values; use forXml11 or forXml11Attribute for those contexts. Encodes control
+ characters the same way as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Content
+ forXml11Content
+ org.owasp.encoder.tag.ForXml11ContentTag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Performs percent-encoding for a component of a URI, such as a query
@@ -498,6 +554,21 @@
java.lang.String forXml(java.lang.String)
forXml(unsafeData)
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.Encode
+ java.lang.String forXml11(java.lang.String)
+ forXml11(unsafeData)
+
Encodes XML and XHTML text content. Does not escape quotes and is unsafe for attribute values; use forXml or forXmlAttribute for those contexts.
@@ -508,6 +579,18 @@
java.lang.String forXmlContent(java.lang.String)
forXmlContent(unsafeData)
+
+
+ Encodes XML 1.1 text content. Does not escape quotes and is unsafe for attribute
+ values; use forXml11 or forXml11Attribute for those contexts. Encodes control
+ characters the same way as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Content
+ forXml11Content
+ org.owasp.encoder.Encode
+ java.lang.String forXml11Content(java.lang.String)
+ forXml11Content(unsafeData)
+
Encodes for XML and XHTML attribute content.
forXmlAttribute
@@ -516,6 +599,17 @@
java.lang.String forXmlAttribute(java.lang.String)
forXmlAttribute(unsafeData)
+
+
+ Encodes for XML 1.1 attribute content. Encodes control characters the same way
+ as forXml11. Use only in XML 1.1 documents.
+
+ forXml11Attribute
+ forXml11Attribute
+ org.owasp.encoder.Encode
+ java.lang.String forXml11Attribute(java.lang.String)
+ forXml11Attribute(unsafeData)
+
Encoder for XML comments. NOT FOR USE WITH (X)HTML CONTEXTS.
diff --git a/jsp/src/main/resources/META-INF/java-encoder.tld b/jsp/src/main/resources/META-INF/java-encoder.tld
index abfcb7a..a676f0c 100644
--- a/jsp/src/main/resources/META-INF/java-encoder.tld
+++ b/jsp/src/main/resources/META-INF/java-encoder.tld
@@ -70,6 +70,27 @@
java.lang.String
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.tag.ForXml11Tag
+ empty
+
+ value to be written out
+ value
+ true
+ true
+ java.lang.String
+
+
Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script
@@ -390,6 +411,21 @@
java.lang.String forXml(java.lang.String)
forXml(unsafeData)
+
+
+ Encodes for XML 1.1 text content and attributes. Like forXml, but the control
+ characters XML 1.1 allows only as character references (U+0001 to U+0008, U+000B,
+ U+000C, U+000E to U+001F and U+007F to U+009F) are written as references such as
+ , and NEL (U+0085) and U+2028 are written as … and 
 so an
+ XML 1.1 processor does not normalize them to a line feed. Use only in XML 1.1
+ documents: XML 1.0 does not allow these character references.
+
+ forXml11
+ forXml11
+ org.owasp.encoder.Encode
+ java.lang.String forXml11(java.lang.String)
+ forXml11(unsafeData)
+
Encodes XML and XHTML text content. Does not escape quotes and is unsafe for attribute values; use forXml or forXmlAttribute for those contexts.
diff --git a/jsp/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java b/jsp/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
index 9fa7664..2c08222 100644
--- a/jsp/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
+++ b/jsp/src/test/java/org/owasp/encoder/tag/TaglibDescriptorTest.java
@@ -105,13 +105,13 @@ static Taglib load(String resource) throws Exception {
}
/**
- * Java source generation is not a JSP context. XML 1.1 tags are tracked
- * separately in issue #131. Deprecated forUri remains for compatibility;
- * deprecation alone must not silently remove a deployed tag/function.
+ * Java source generation is not a JSP context, so forJava is the only
+ * facade method without a tag and function. Deprecated forUri remains for
+ * compatibility; deprecation alone must not silently remove a deployed
+ * tag/function.
*/
public void testAdvancedMatchesSupportedFacade() throws Exception {
- Set unsupported = new TreeSet(Arrays.asList(
- "forJava", "forXml11", "forXml11Content", "forXml11Attribute"));
+ Set unsupported = new TreeSet(Arrays.asList("forJava"));
Set expected = new TreeSet();
for (Method method : Encode.class.getMethods()) {
if (Modifier.isStatic(method.getModifiers()) && method.getName().startsWith("for")
@@ -214,7 +214,7 @@ public void testBasicIsSubsetOfAdvanced() throws Exception {
Set expectedBasic = new TreeSet(Arrays.asList(
"forCDATA", "forCssString", "forCssUrl", "forHtml", "forHtmlAttribute",
"forHtmlContent", "forHtmlUnquotedAttribute", "forJavaScript", "forJson",
- "forUri", "forUriComponent", "forXml", "forXmlAttribute", "forXmlContent"));
+ "forUri", "forUriComponent", "forXml", "forXml11", "forXmlAttribute", "forXmlContent"));
assertEquals("basic tags", expectedBasic, basic.tagClasses.keySet());
assertEquals("basic functions", expectedBasic, basic.functionSignatures.keySet());
for (Map.Entry tag : basic.tagClasses.entrySet()) {