RFC 7351
A Media Type for XML Patch Operations
A Media Type for XML Patch Operations π
π Okay bestie, paperwork first π This is RFC 7351, written by E. Wilde at UC Berkeley and published in August 2014. It's an Independent Submission in the Informational category, with ISSN 2070-1721. The header doesn't list anything it obsoletes or updates, so it just sits there, minding its own business π¦
Abstract β¨
Okay so the XML patch document format is a way to write down a list of changes (patch operations) that get applied to an XML document, all wrapped in an XML structure π§ It's built on top of RFC 5261. This spec also registers the media type application/xml-patch+xml, so you can send these patch docs around in stuff like HTTP conversations π
Status of This Memo πΈ
This doc is not an Internet Standards Track spec. It's published just for information, no cap π
It's a contribution to the RFC Series, independent of any other RFC stream. The RFC Editor chose to publish it at their discretion, and they make no claims about whether it's worth implementing or deploying. Anything the RFC Editor approves isn't a candidate for any level of Internet Standard, see Section 2 of RFC 5741 π
For the current status, any errata, and how to send feedback, check http://www.rfc-editor.org/info/rfc7351 π
Copyright Notice π
The legal bit, kept exact so nobody gets confused π«Ά
Copyright (c) 2014 IETF Trust and the persons identified as the
document authors. All rights reserved.
So basically, the IETF Trust and the authors own the copyright. This doc follows BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they were on the publication date. Please actually read those, bestie, because they spell out your rights and restrictions π
Table of Contents π
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Patch Documents . . . . . . . . . . . . . . . . . . . . . . . 3
2.1. Patch Document Format . . . . . . . . . . . . . . . . . . 3
2.2. Patch Examples . . . . . . . . . . . . . . . . . . . . . 5
3. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 5
4. Security Considerations . . . . . . . . . . . . . . . . . . . 7
5. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 7
6. References . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.1. Normative References . . . . . . . . . . . . . . . . . . 7
6.2. Informative References . . . . . . . . . . . . . . . . . 7
Appendix A. Implementation Hints . . . . . . . . . . . . . . . . 9
A.1. Matching Namespaces . . . . . . . . . . . . . . . . . . . 9
A.2. Patching Namespaces . . . . . . . . . . . . . . . . . . . 10
Appendix B. ABNF for RFC 5261 . . . . . . . . . . . . . . . . . 12
1. Introduction β¨
Okay, so XML ([RFC7303]) is the go-to format for trading and storing structured data π HTTP PATCH ([RFC5789]) extends HTTP ([RFC7231]) with a method for making partial changes to resources. The catch is that HTTP PATCH needs the patch document to be sent along with the request. That's why it's super useful to have standard patch formats, identified by media types, for popular media types π
The XML patch media type application/xml-patch+xml is an XML document structure for expressing a sequence of operations to apply to a target XML document. It's made for use with the HTTP PATCH method π¦ Servers get to pick whichever patch formats they want to accept. application/xml-patch+xml could be a simple default that people use unless a server decides to go with a different, maybe fancier, patch format for XML π
The patch document format is based on the XML patch framework from RFC 5261 ([RFC5261]). RFC 5261 does define a concrete syntax, plus the media type application/patch-ops-error+xml for error documents. But it only defines XML Schema (XSD) types for patch operations ([W3C.REC-xmlschema-1-20041028]). The concrete document format and the media type for patch operations get defined in an XSD in this spec π
This spec relies on RFC 5261 but also needs the errata reported so far to be taken into account. Most of the errata are about how RFC 5261 uses XML Path Language (XPath) as the expression language for picking where a patch goes. The problem is that XPath's data model doesn't have enough info to tell whether a selector can actually be used for a patch operation or should cause an error. This is especially true for namespaces: XPath doesn't expose namespace declaration attributes, but the patch model needs them to decide whether a namespace patch is allowed π Appendix A has more on the general problem and the errata reports π
2. Patch Documents πΈ
The next sections describe and illustrate the XML patch document format π§
2.1. Patch Document Format π
The XML patch document format is based on a simple schema. It uses a patch element as the document element, and it allows any sequence of add, remove, and replace elements as children of the document element. These children follow the semantics defined in RFC 5261. That means each element counts as one individual patch operation, and the result of each operation is a patched XML document, which becomes the target XML document for the next operation π₯
Here's a simple example patch document with a single operation. It adds a new attribute called new-attribute to the document element of the target XML document. An XML patch document always uses a patch element in the urn:ietf:rfc:7351 namespace as its document element. That element holds zero or more patch operation elements, which are also in the urn:ietf:rfc:7351 namespace β¨
<p:patch xmlns:p="urn:ietf:rfc:7351">
<p:add sel="*" type="@new-attribute">value</p:add>
</p:patch>
Next up is a more complex example. It uses the example from RFC 5261, Section A.18, but the example namespaces get changed to example.com URIs. It uses the same patch element and XML namespace as the simpler one. It shows the general structure of an XML patch document with multiple operations, plus an example of each operation π
<p:patch xmlns="http://example.com/ns1"
xmlns:y="http://example.com/ns2"
xmlns:p="urn:ietf:rfc:7351">
<p:add sel="doc/elem[@a='foo']">
<!-- This is a new child -->
<child id="ert4773">
<y:node/>
</child>
</p:add>
<p:replace sel="doc/note/text()">Patched doc</p:replace>
<p:remove sel="*/elem[@a='bar']/y:child" ws="both"/>
<p:add sel="*/elem[@a='bar']" type="@b">new attr</p:add>
</p:patch>
See how both the patch document element and the patch operation elements live in the same XML namespace? That's because RFC 5261 only defines types for the patch operation elements, which can then be reused in schemas to define concrete patch elements π¦
RFC 5261 defines XSD ([W3C.REC-xmlschema-1-20041028]) types for the patch operations. The schema for the XML patch media type is based on those types. They're imported as rfc5261.xsd in the schema below. The schema defines a patch document element and then allows an unlimited, possibly empty, sequence of the add, remove, and replace operation elements. Those are directly based on the matching types from the RFC 5261 schema π
<xs:schema targetNamespace="urn:ietf:rfc:7351"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="rfc5261.xsd"/>
<xs:element name="patch">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="add" type="add"/>
<xs:element name="remove" type="remove"/>
<xs:element name="replace" type="replace"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
2.2. Patch Examples π
The semantics of XML patch operations are defined by RFC 5261, so go check the many examples in that spec for more XML patch document examples π Every example in RFC 5261 works as an example for the XML patch media type, with two small changes in mind π
The two differences: XML patch documents always use the patch element as the document element, and both the patch element and the individual operation elements have to be in the XML namespace urn:ietf:rfc:7351 π«Ά
Take the patch example from RFC 5261, Appendix A.1, "Adding an Element". The patch gets applied to this XML document:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<note>This is a sample document</note>
</doc>
The patch example is based on this patch document, with the element and namespace changes from above applied:
<?xml version="1.0" encoding="UTF-8"?>
<p:patch xmlns:p="urn:ietf:rfc:7351">
<p:add sel="doc"><foo id="ert4773">This is a new child</foo></p:add>
</p:patch>
And applying the patch gives this XML document:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<note>This is a sample document</note>
<foo id="ert4773">This is a new child</foo></doc>
5. Acknowledgements β¨
Huge thanks to Bas de Bakker, Tony Hansen, Bjoern Hoehrmann, and Julian Reschke for sharing comments and suggestions. You all are the real MVPs π«Άπ
6. References π
6.1. Normative References
- [RFC3470] Hollenbeck, S., Rose, M., and L. Masinter, "Guidelines for the Use of Extensible Markup Language (XML) within IETF Protocols", BCP 70, RFC 3470, January 2003.
- [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
- [RFC5261] Urpalainen, J., "An Extensible Markup Language (XML) Patch Operations Framework Utilizing XML Path Language (XPath) Selectors", RFC 5261, September 2008.
- [RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, January 2013.
- [RFC7303] Thompson, H. and C. Lilley, "XML Media Types", RFC 7303, July 2014.
6.2. Informative References
- [Err3477] RFC Errata, "Errata ID 3477", RFC 5261.
- [Err3478] RFC Errata, "Errata ID 3478", RFC 5261.
- [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, March 2010.
- [RFC7231] Fielding, R. and J. Reschke, "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, June 2014.
- [W3C.REC-DOM-Level-3-Core-20040407] Robie, J., Wood, L., Champion, M., Hegaret, P., Nicol, G., Le Hors, A., and S. Byrne, "Document Object Model (DOM) Level 3 Core Specification", World Wide Web Consortium Recommendation REC-DOM-Level-3-Core-20040407, April 2004,
<http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407>. - [W3C.REC-xml-20081126] Sperberg-McQueen, C., Yergeau, F., Paoli, J., Maler, E., and T. Bray, "Extensible Markup Language (XML) 1.0 (Fifth Edition)", World Wide Web Consortium Recommendation REC-xml-20081126, November 2008,
<http://www.w3.org/TR/2008/REC-xml-20081126>. - [W3C.REC-xml-names-20091208] Hollander, D., Layman, A., Bray, T., Tobin, R., and H. Thompson, "Namespaces in XML 1.0 (Third Edition)", World Wide Web Consortium Recommendation REC-xml-names-20091208, December 2009,
<http://www.w3.org/TR/2009/REC-xml-names-20091208>. - [W3C.REC-xmlschema-1-20041028] Thompson, H., Beech, D., Maloney, M., and N. Mendelsohn, "XML Schema Part 1: Structures Second Edition", World Wide Web Consortium Recommendation REC-xmlschema-1-20041028, October 2004,
<http://www.w3.org/TR/2004/REC-xmlschema-1-20041028>. - [W3C.REC-xpath-19991116] DeRose, S. and J. Clark, "XML Path Language (XPath) Version 1.0", World Wide Web Consortium Recommendation REC-xpath-19991116, November 1999,
<http://www.w3.org/TR/1999/REC-xpath-19991116>. - [W3C.REC-xpath20-20101214] Boag, S., Berglund, A., Kay, M., Simeon, J., Robie, J., Chamberlin, D., and M. Fernandez, "XML Path Language (XPath) 2.0 (Second Edition)", World Wide Web Consortium Recommendation REC-xpath20-20101214, December 2010,
<http://www.w3.org/TR/2010/REC-xpath20-20101214>.
Appendix A. Implementation Hints π§
This section is informative. πΈ It describes some issues that might be interesting for implementers, but it might also be interesting for users of XML patch who want to understand some of the differences between standard XPath 1.0 processing and the processing model of selectors in RFC 5261. Basically, it's the tea on where XPath 1.0 and RFC 5261 part ways π΅
Okay so, the issues in the following two sections have been identified as technical issues with RFC 5261 and have been filed as errata. Implementers who are into using XML patch are encouraged to take those errata into account when implementing XML patch documents. The "Matching Namespaces" issue in Appendix A.1 was filed as RFC Errata ID 3477 [Err3477], and the "Patching Namespaces" issue in Appendix A.2 was filed as RFC Errata ID 3478 [Err3478]. Bookmark these, bestie π
A.1. Matching Namespaces
RFC 5261 defines standard rules for matching prefixed names in expressions: any prefixes are interpreted according to the namespace bindings of the diff document (the document that the expression is applied against). So each prefixed name can be interpreted in the context of the diff document π
For unprefixed names in expressions, the rules depart from XPath 1.0 [W3C.REC-xpath-19991116]. XPath 1.0 defines that unprefixed names in expressions match namespace-less names (i.e., there is no "default namespace" for names used in XPath 1.0 expressions). RFC 5261 requires, however, that unprefixed names in expressions use the default namespace of the diff document (if there is one). This means you can't just take a selector from a patch document and evaluate it in the context of the diff document using the XPath 1.0 rules, because that would interpret unprefixed names incorrectly. As a consequence, you can't simply take an XPath 1.0 processor and use it to evaluate XML patch selectors in the context of the diff document π
Now here's the plot twist π¦ XPath 2.0 [W3C.REC-xpath20-20101214] extends XPath 1.0's simple model with different processing rules for unprefixed names: they are matched against the URI of the "default element/type namespace", which is defined as part of an expression's static context. In some XPath 2.0 applications this can be set. XSL Transformations (XSLT) 2.0, for example, can define an "xpath-default-namespace", which is then used to match unprefixed names in expressions. So, by using an XPath 2.0 implementation that lets you set this URI, and setting it to the default namespace of the diff document (or leaving it undefined if there is no such default namespace), you can use an out-of-the-box XPath 2.0 implementation to evaluate XML patch selectors. Iconic π
Please keep in mind, though, that evaluating selectors is only one part of applying patches. When it comes to applying the actual patch operation, neither XPath 1.0 nor XPath 2.0 is sufficient, because they do not preserve some of the information from the XML syntax (specifically namespace declarations) that is required to correctly apply patch operations. The following section describes this issue in more detail π
Please note that [RFC5261], Section 4.2.2 on namespace matching explains XPath 2.0's rules incorrectly. For this reason, RFC Errata ID 3477 is available for Section 4.2.2 of RFC 5261. π©
A.2. Patching Namespaces
One of the issues when patching namespaces based on XPath is that XPath exposes namespaces differently than the XML 1.0 [W3C.REC-xml-20081126] syntax for XML namespaces [W3C.REC-xml-names-20091208]. In the XML syntax, a namespace is declared with an attribute using the reserved name or prefix "xmlns", and this results in the namespace being available recursively through the document tree. In XPath, the namespace declaration is not exposed as an attribute (i.e., the attribute, although syntactically an XML attribute, is not accessible in XPath), but the resulting namespace nodes are exposed recursively through the tree. Two different vibes, same tree π³
RFC 5261 uses the terms "namespace declaration" and "namespace" almost interchangeably, but it's important to keep in mind that the namespace declaration is an XML syntax construct that is unavailable in XPath, while the namespace itself is a logical construct that is not visible in the XML syntax but is a result of a namespace declaration. The intent of RFC 5261 is to patch namespaces as if namespace declarations were patched. Thus, it only allows patching namespace nodes on the element nodes where the namespace has been declared. π
Patching namespaces in XML patch is supposed to "emulate" the effect of actually changing the namespace declaration (which is why a namespace can only be patched at the element where it has been declared). Therefore, when patching a namespace, even though XPath's "namespace" axis is used, implementations have to make sure that not only the single selected namespace node is patched, but also all namespace nodes resulting from the namespace declaration of this namespace are patched accordingly. π
This means that an implementation might have to descend into the tree, matching all namespace nodes with the selected prefix/URI pair recursively, until it encounters leaf elements or namespace declarations with the same prefix it is patching. Determining this requires access to the diff document beyond XPath, because in XPath itself, namespace declarations are not represented, so such a recursive algorithm wouldn't know when to stop. Consider the following document:
<x xmlns:a="tag:42">
<y xmlns:a="tag:42"/>
</x>
If this document is patched with a selector of /x/namespace::a, then only the namespace node on element x should be patched, even though the namespace node on element y has the same prefix/URI combination as the one on element x. However, determining that the repeated namespace declaration was present at all on element y is impossible when using XPath alone. This means implementations must have an alternative way to determine the difference between the document above and this one:
<x xmlns:a="tag:42">
<y/>
</x>
In this second example, patching with a selector of /x/namespace::a should indeed change the namespace nodes on elements x and y, because they both have been derived from the same namespace declaration. Plot twist, but make it make sense π§©
The conclusion of these considerations is that, for implementing XML patch, access closer to the XML syntax (specifically access to namespace declarations) is necessary. As a result, implementations attempting to exclusively use the XPath model for implementing XML patch will fail to correctly address certain edge cases (such as the one shown above). π
Note that XPath's specific limitations do not mean it's impossible to use XML technologies other than XPath. The Document Object Model (DOM) [W3C.REC-DOM-Level-3-Core-20040407], for example, does expose namespace declaration attributes as regular attributes in the document tree, so they could be used to differentiate between the two variants shown above. β¨
Please note that RFC 5261, Section 4.4.3 (on replacing namespaces) mixes the terms "namespace declaration" and "namespace". For this reason, RFC Errata ID 3478 is available for Section 4.4.3 of RFC 5261. π
Appendix B. ABNF for RFC 5261 β¨
RFC 5261 [RFC5261] doesn't have an ABNF grammar for the allowed subset of XPath expressions π but it does have an XSD-based grammar in its type definition for operation types. So to make life easier for implementers, this appendix has an ABNF grammar derived from those XSD expressions in RFC 5261 π In the grammar below, "xpath" is the definition for the allowed XPath expressions for remove and replace operations, and "xpath-add" is the one for add operations. All the production names are the same ones used in the XSD-based grammar of RFC 5261 π
anychar = %x00-ffffffff
ncname = 1*%x00-ffffffff
qname = [ ncname ":" ] ncname
aname = "@" qname
pos = "[" 1*DIGIT "]"
attr = ( "[" aname "='" 0*anychar "']" ) /
( "[" aname "=" DQUOTE 0*anychar DQUOTE "]" )
valueq = "[" ( qname / "." ) "=" DQUOTE 0*anychar DQUOTE "]"
value = ( "[" ( qname / "." ) "='" 0*anychar "']" ) / valueq
cond = attr / value / pos
step = ( qname / "*" ) 0*cond
piq = %x70.72.6f.63.65.73.73.69.6e.67.2d
%x69.6e.73.74.72.75.63.74.69.6f.6e
; "processing-instruction", case-sensitive
"(" [ DQUOTE ncname DQUOTE ] ")"
pi = ( %x70.72.6f.63.65.73.73.69.6e.67.2d
%x69.6e.73.74.72.75.63.74.69.6f.6e
; "processing-instruction", case-sensitive
"(" [ "'" ncname "'" ] ")" ) / piq
id = ( %x69.64 ; "id", case-sensitive
"(" [ "'" ncname "'" ] ")" ) /
( %x69.64 ; "id", case-sensitive
"(" [ DQUOTE ncname DQUOTE ] ")" )
com = %x63.6f.6d.6d.65.6e.74 ; "comment", case-sensitive
"()"
text = %x74.65.78.74 ; "text", case-sensitive
"()"
nspa = %x6e.61.6d.65.73.70.61.63.65 ; "namespace", case-sensitive
"::" ncname
cnodes = ( text / com / pi ) [ pos ]
child = cnodes / step
last = child / aname / nspa
xpath = [ "/" ] ( ( id [ 0*( "/" step ) "/" last ] ) /
( 0*( step "/" ) last ) )
xpath-add = [ "/" ] ( ( id [ 0*( "/" step ) "/" child ] ) /
( 0*( step "/" ) child ) )
Heads up, bestie π The "ncname" production above doesn't fully capture the constraints of the original XSD-based definition, where it's defined as "\i\c*". Just keep that in mind when you're reading it π§
DIGIT and DQUOTE are defined by the ABNF specification [RFC5234] π¦
Author's Address π
Erik Wilde UC Berkeley
EMail: dret@berkeley.edu URI: http://dret.net/netdret/
And that's a wrap, bestie! πβ¨
π¦ where this page comes from
- ietf: rfc7351 2014-08
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms