To demonstrate creating a custom operation, consider that we have a task where we need to convert an attribute into an element and insert it inside another element. A specific example would be if you have a project with a variety of image elements where a deprecated alt attribute was used for the description and you want to convert all instances of that attribute into an element with the same name and insert it as the first child of the image element.
Thus, our task is to convert this attribute into an element with the same name and insert it as the first child of the image element.
A new operation requires an XQuery Update script and an XML Refactoring operation descriptor file.
(:
XQuery document used to implement 'Convert attribute to element' operation from XML Refactoring tool.
:)
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "xml";
declare option output:indent "no";
(: Local name of the attribute's parent element. :)
declare variable $element_localName as xs:string external;
(: Namespace of the attribute's parent element. :)
declare variable $element_namespace as xs:string external;
(: The local name of the attribute to be converted :)
declare variable $attribute_localName as xs:string external;
(: The namespace of the attribute to be converted :)
declare variable $attribute_namespace as xs:string external;
(: Local name of the new element. :)
declare variable $new_element_localName as xs:string external;
(: Namespace of the new element. :)
declare variable $new_element_namespace as xs:string external;
(: Convert attribute to element:)
for $node in //*
(: Find the attribute to convert :)
let $attribute :=
$node/@*[local-name() = $attribute_localName and
($attribute_namespace = '<ANY>' or $attribute_namespace = namespace-uri())]
(: Compute the prefix for the new element to insert :)
let $prefix :=
for $p in in-scope-prefixes($node)
where $new_element_namespace = namespace-uri-for-prefix($p, $node)
return $p
(: Compute the qname for the new element to insert :)
let $new_element_qName :=
if (empty($prefix) or $prefix[1] = '') then $new_element_localName
else $prefix[1] || ':' || $new_element_localName
where ('<ANY>' = $element_localName or local-name($node) = $element_localName) and
($element_namespace = '<ANY>' or $element_namespace = namespace-uri($node))
return
if (exists($attribute)) then
(insert node element {QName($new_element_namespace, $new_element_qName)}
{string($attribute)} as first into $node,
delete node $attribute)
else ()
After you have developed the XQuery script, you have to create an XML Refactoring operation descriptor. This descriptor is used by application to load the operation details such as name, description, or parameters.
<?xml version="1.0" encoding="UTF-8"?> <refactoringOperationDescriptor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://oxygenxml.com/ns/xmlRefactoring" id="convert-attribute-to-element" name="Convert attribute to element"> <description>Converts the specified attribute to an element. The new element will be inserted as first child of the attribute's parent element.</description> <script type="XQUERY_UPDATE" href="convert-attribute-to-element.xq"/> <parameters> <description>Specify the attribute to be converted to element.</description> <section label="Parent element"> <elementParameter id="elemID"> <localName label="Name" name="element_localName" allowsAny="true"> <description>The local name of the attribute's parent element.</description> </localName> <namespace label="Namespace" name="element_namespace" allowsAny="true"> <description>The local name of the attribute's parent element</description> </namespace> </elementParameter> </section> <section label="Attribute"> <attributeParameter dependsOn="elemID"> <localName label="Name" name="attribute_localName"> <description>The name of the attribute to be converted.</description> </localName> <namespace label="Namespace" name="attribute_namespace" allowsAny="true"> <description>The namespace of the attribute to be converted.</description> </namespace> </attributeParameter> </section> <section label="New element"> <elementParameter> <localName label="Name" name="new_element_localName"> <description>The name of the new element.</description> </localName> <namespace label="Namespace" name="new_element_namespace"> <description>The namespace of the new element.</description> </namespace> </elementParameter> </section> </parameters> </refactoringOperationDescriptor>
After you have created these files, copy them into a folder scanned by Oxygen XML Editor when it loads the custom operation. When the XML Refactoring tool is started again, you will see the created operation.