Insert / Move Element Attribute

Questions about XML that are not covered by the other forums should go here.
WSMC511
Posts: 4
Location: Los Angeles, CA USA

Insert / Move Element Attribute

Tue Dec 29, 2015 4:51 am

I searched quite a bit for threads on two things but could not find anything.

I am trying to do two things:

1. Insert element and attribute
2. Move existing element and attribute

I apologize if I have not identified the parts of the XML file that need to be modified.

Here is what I have now:

Code: Select all

<App action='A' id='1'>
   <BaseVehicle id='3702'/>
   <SubModel id='430'/>
   <EngineBase id='396'/>
   <PartType id='5764'/>
   <Part>17-0012</Part>
   <Note>Turbo Wheel and Shaft Included<Note/>
</App>


First I need to insert a new element with data "<Qty>1</Qty>" above the <PartType element.

The second thing I need to do is move the entire <Note></Note> element with the data to a new position. This element and data should be positioned above quantity. The end result should look like:

Code: Select all

<App action="A" id="1">
    <BaseVehicle id="3702" />
    <SubModel id="430" />
    <EngineBase id="396" />
    <Note>Turbo Wheel and Shaft Included</Note>
    <Qty>1</Qty>
    <PartType id="5764" />
    <Part>17-0012</Part>
  </App>


Any guidance on how I can do this on my own using Oxygen XML would be great.

Thanks,

Johnny
radu_pisoi
Posts: 328
Location: Craiova

Re: Insert / Move Element Attribute

Wed Dec 30, 2015 5:35 pm

Hi,

Both operations can be done using the XML Refactoring tool that is available in the application starting with version 17. To access this tool, select the XML Refactoring action from the Tools menu.

For instance, to insert a new element you can use the predefined Insert XML Fragment operation. After you select the operation, in the next step you have to specify its parameters as follows:
XML Fragment: <Qty>1</Qty>
XPath: PartType
Position: After

For the second request, to move an element, there is no predefined operation. I've added an issue to be added in a further oXygen version.

The good news is that this tool is extensible and it accepts custom operations. An XML Refactoring operation is defined as a pair of resources:
* an XQuery Update script or XSLT stylesheet that Oxygen XML Editor will run in order to refactor the XML files.
* an XML Operation Descriptor file that contains information about the operation, such as the name, description, and parameters.

move-element.xq

Code: Select all

xquery version "3.0" encoding "utf-8";

(:
    XQuery document used to implement 'Move element' operation from the XML Refactor tool.   
:)

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace saxon = "http://saxon.sf.net/";

declare option output:method "xml";
declare option output:indent "no";

(: The XPath that localize the elements to be moved. :)
declare variable $context_element_xpath as xs:string external;
declare variable $element_to_move_xpath as xs:string external;

(: The XPath that localize the anchor elements. The element will be moved relatively to this node. :)
declare variable $element_anchor_xpath as xs:string external;

(: The insert position relative to the node determined by the 'Element XPath' expression. :)
declare variable $insert_position as xs:string external;


let $cElements := saxon:evaluate($context_element_xpath)

for $elem in $cElements
let $elemsToMove := saxon:evaluate(concat('$p1/', $element_to_move_xpath), $elem)
let $anchorElements := saxon:evaluate(concat('$p1/', $element_anchor_xpath), $elem)
return   
  if (count($elemsToMove) > 0 and count($elemsToMove) = count($anchorElements))
  then
    (
    for $eMove in $elemsToMove
    let $aNode := $anchorElements[position()]
    return
      if($eMove/ancestor::node() = $elem and $aNode/ancestor::node() = $elem) then (
     
      switch ($insert_position)
        case 'firstChild'             
            return insert nodes $eMove as first into $aNode
        case 'lastChild'
            return insert nodes $eMove  as last into $aNode
        case 'after'
           return insert nodes $eMove  after $aNode
        case 'before'
           return insert nodes $eMove  before $aNode
         default return () ,     
        delete node $eMove
      ) else ()       
    ) else ( )


move-element.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Descriptor for 'Rename attribute' operation.
-->
<refactoringOperationDescriptor
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.oxygenxml.com/ns/xmlRefactoring" id="move-element" name="Move Element">
 
    <description>Move one or more elements</description>   
    <script type="XQUERY_UPDATE" href="move-element.xq"/>
    <category>Elements</category>
    <parameters>
        <description>Specify the elements to be moved and their new location.</description>
       
      <parameter type="TEXT" name="context_element_xpath" label="Context Element">
        <description>The XPath expression that identifies one or more context elements.</description>
        </parameter>
 
      <parameter type="TEXT" name="element_to_move_xpath" label="Element to Move">
        <description>The XPath expression that identifies one or more elements to move.
          The Xpath expression is relative to the context node.</description>
      </parameter>
     
      <parameter type="TEXT" name="element_anchor_xpath" label="Anchor Element">
        <description>The XPath expression that identifies one or more anchor elements.
          The Xpath expression is relative to the context node.</description>
      </parameter>
     
     
      <parameter label="Position" type="TEXT" name="insert_position">             
        <description>The insert position relative to the anchor element.</description>
        <possibleValues onlyPossibleValuesAllowed="true">
          <value name="before">Before</value>
          <value name="after" default="true">After</value>
          <value name="firstChild">First child</value>
          <value name="lastChild">Last child</value>
        </possibleValues>
      </parameter>
    </parameters>
</refactoringOperationDescriptor>


Please save these files in a separate folder. After that, you have to specify the path to this folder in the preferences page: XML / XML Refactoring. This lets application to know where are the additional operations.

Finally, you have to display the XML Refactoring dialog and choose the new added operation. Specify the next parameters:
Context Element: //App
Element to Move: Note
Anchor Element: Qty
Position: Before
Radu Pisoi
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
WSMC511
Posts: 4
Location: Los Angeles, CA USA

Re: Insert / Move Element Attribute

Thu Dec 31, 2015 1:03 am

Radu,

Thanks so much for you guidance.

I have followed the <Qty>1</Qty> without a problem.

I created/saved both the .xml and .xq files. When I go to Options/Preferences/XML/XML Refactoring and use the open folder icon, I can not see my .xml or .xq files. I can not add.

Please let me me know what I am doing wrong.

Cheers,
radu_pisoi
Posts: 328
Location: Craiova

Re: Insert / Move Element Attribute

Thu Dec 31, 2015 10:11 am

Hi,

WSMC511 wrote:I created/saved both the .xml and .xq files. When I go to Options/Preferences/XML/XML Refactoring and use the open folder icon, I can not see my .xml or .xq files. I can not add.


The option Load additional refactoring operations from that appears in the XML > XML Refactoring preferences page is used to specify a folder for loading custom XML refactoring operations. So, you have to select the folder where you've saved the .xml and .xq files.
Radu Pisoi
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
WSMC511
Posts: 4
Location: Los Angeles, CA USA

Re: Insert / Move Element Attribute

Thu Dec 31, 2015 5:22 pm

Radu,

Thank for all of the guidance.

Which refractoring operation would I use. I have opened them all but can not figure out which would follow your instructions:

"Finally, you have to display the XML Refactoring dialog and choose the new added operation. Specify the next parameters:
Context Element: //App
Element to Move: Note
Anchor Element: Qty
Position: Before"

Cheers,

Johnny
WSMC511
Posts: 4
Location: Los Angeles, CA USA

Re: Insert / Move Element Attribute

Fri Jan 01, 2016 9:23 pm

Radu,

Happy New Year!

If you could please assist me.

I added the folder as per your instructions. When using the refactoring operations pop up screen, which operation would I use? I looked at all of them and can not figure out which to use.

Any guidance would be appreciated.

Cheers,

Johnny
radu_pisoi
Posts: 328
Location: Craiova

Re: Insert / Move Element Attribute

Mon Jan 04, 2016 11:10 am

Hi,

Happy New Year!

The name of operation that allows you to move an element is Move Element.

Please note that before the version 17.1, the custom operations are allowed only in the Enterprise edition. So, if you don't have the Enterprise edition please install the latest version of oXygen 17.1 (build 2015121117) where the XML Refactoring operations are also available in the Professional edition.
Radu Pisoi
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Return to “General XML Questions”

Who is online

Users browsing this forum: No registered users and 3 guests