120 likes | 244 Views
Jari Urpalainen IETF62 Minneapolis. XML Patch Operations based on XPath selectors. Purpose was to remove the overlapping parts of xcap-diff and partial-pidf which reference patch-ops ~XCAP PUT and DELETE semantics. Patch operations are embedded within a transported XML document
E N D
Jari Urpalainen IETF62 Minneapolis XML Patch Operations based on XPath selectors
Purpose was to remove the overlapping parts of xcap-diff and partial-pidf which reference patch-ops ~XCAP PUT and DELETE semantics. Patch operations are embedded within a transported XML document Uses XPath 1.0 compatible selectors Combines several requests: <add>, <replace> and <remove> with optional data onto a single XML doc XML Schema defines only types without any targetNamespace -> the elements inherit the namespace of the including Schema Short overview
Changes • The names in location steps are fully namespace qualified. • The framing document (xcap-diff, pidf-diff etc.) carries all the namespace definitions that are needed to apply the patch requests • The added or modified data content is also fully namespace qualified.
Open Issues/BUGS • Whitespace text node handling in <add> and <remove> • In addition to above lack of XPath data model nodes: namespaces, comments and processing instructions • Lack of the ability to say: I want to add these nodes immediately before/after this element that already exist within the patched document
Adding namespace definitions • namespace axis of XPath 1.0 does the trick <add sel="root" type="namespace::prefix">urn:xml:ns:something</add> • value of “sel” selects the element where the namespace definition will be added (similar to adding an attribute with “@”) <remove sel="root/namespace::prefix"/> <replace sel="root/namespace::prefix">urn:xml:ns:something</replace> • value of “sel” selects the namespace node
<add> • except attribute and namespace nodes this will always (by default) append elements, text nodes, comments and processing instructions as the last child(ren) <add sel="root"> <!-- This is a comment --> <new-element a=”1”/><new-element a=”2”/></add> • This allows an easy handling of whitespace text nodes as well as several siblings at the same time
the value of 'sel' attribute selects a single unique element from the patched doc 'pos' attribute: “to” [default], “before”, “after” “before” = immediate preceding sibling node “after” = immediate following sibling node “to” = last child(ren) node or attribute/namespace 'type' attribute; values: node() [default], text(), @attr, namespace::prefix child element(s) or text content of <add> = the new/updated XML fragment(s) or values for ns/attr <add> parameters
Add before and after • XPath 1.0 defines axises: preceding-sibling and following-sibling which could be used: <add sel="root/elem[@a='1']" type="preceding-sibling::node()[1][self::comment()]">This is a comment</add> • instead a much simpler model using “pos” attribute can be used: <add sel="root/elem[@a='1']" pos=”before"><!-- This is a comment --></add> <add sel="root/elem[@a='1']" pos=”after"> <!-- This is a new added node --><new-node a=”1”> </add>
<replace> • Only one “sel” selector (must locate a unique node) • Last location step includes comment(), processing-instruction(“x”) and text(). <replace sel="root/elem[@a='1']"><update/></replace> <replace sel="root/@a">new attr value</replace> <replace sel="root/namespace::prefix">urn:new</replace> <replace sel="root/comment()[1]">This is a new comment</replace> <replace sel="root/processing-instruction('foo')">bar="foobar"</replace> <replace sel="root/elem[1]/text()[1]">This is the new text content</replace>
<remove> • whitespace text nodes somewhat problematic A.<remove sel="root/text()[1]"/> <remove sel="root/elem[@a='1']"/> B.<remove sel="root/text()[1] | root/elem[@a='1']"/> C.<remove sel="root/elem[@a='1']/preceding-sibling::text()[1] | root/elem[@a='1']"/> The proposed model (similar to C, but simpler): • in addition to 'sel' an optional whitespace attribute 'ws': "before", "after", "both", "none" [default] <remove sel="root/elem[@a='1']" ws="before"/>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE document [ <!ENTITY ncname "[^:\I][^:\C]*"> <!ENTITY qname "(&ncname;:)?&ncname;"> <!ENTITY aname "@&qname;"> <!ENTITY pos_t "\[\d+\]"> <!ENTITY attr_t "\[&aname;=('|")[.\n]*('|")\]"> <!ENTITY name_t "\[(&qname;|\.)=('|")[.\n]*('|")\]"> <!ENTITY cond "(&attr_t;|&name_t;)?(&pos_t;)?|(&pos_t;)?(&attr_t;|&name_t;)?"> <!ENTITY step "(&qname;|\*)(&cond;)?"> <!ENTITY pi "processing-instruction\((('|")&qname;('|"))?\)"> <!ENTITY comm "comment\(\)"> <!ENTITY text "text\(\)"> <!ENTITY nspace "namespace::&ncname;"> <!ENTITY last "&step;|&aname;|&nspace;|(&comm;(&pos_t;)?)|&text;(&pos_t;)?|π(&pos_t;)?"> ]> <xsd:schema ... <xsd:simpleType name="xpath"> <xsd:restriction base="xsd:string"> <xsd:pattern value="(&step;/)*(&last;)"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>
Common model for applying XML changes XML Schemas include patch-ops which is only a framework for patch operations Content-Types are defined according to the including schema within xcap-diff and pidf-diff etc. As these operations describe the model to patch the full XPath 1.0 data model node types, applications may either extend or restrict these as desired Impact on xcap-diff & pidf-diff etc.