Can OxygenXML batch relocate XML Blocks?

Questions about XML that are not covered by the other forums should go here.
binar
Posts: 26
Joined: Wed Apr 10, 2019 7:43 pm

Can OxygenXML batch relocate XML Blocks?

Post by binar »

Greetings,
Does OxygenXML have the capability to relocate XML blocks in order to fix validation errors? The two examples below provide a visual as to what I mean when I say, "relocate an XML block".

Example #1 shows the

Code: Select all

<sequentialList>data</sequentialList>
XML block in the wrong location and thereby causing a validation failure. Can OxygenXML batch fix 200 data modules so it reflects what is shown in Example #2 and thereby fixing the validation failure?

In other words, is the XML Refactoring Tool powerful enough to instruct OxygenXML so it moves the

Code: Select all

<sequentialList>data</sequentialList>
XML block (with all three listItem tag data included as well) so it precedes the closing

Code: Select all

</para>
tag belonging to the Parent Paragraph as shown in Example #2?

Additionally, can the Perl RegEx be designed to only target the closing

Code: Select all

</para>
preceding the opening

Code: Select all

<sequentialList>
tag so it does not confuse it with other closing

Code: Select all

</para>
tags found elsewhere inside the same XML file?

Example #1: Validation Fails:

Code: Select all

<para>Parent Paragraph:</para>
<sequentialList>
<listItem><para>Subordinate Para1</para></listItem>
<listItem><para>Subordinate Para2</para></listItem>
<listItem><para>Subordinate Para3</para></listItem>
</sequentialList>
Example #2: Validation Error Free:

Code: Select all

<para>Parent Paragraph:<sequentialList>
<listItem><para>Subordinate Para1</para></listItem>
<listItem><para>Subordinate Para2</para></listItem>
<listItem><para>Subordinate Para3</para></listItem>
</sequentialList></para>
If OxygenXML can successfully execute such an operation I will be blown away with the power this software has designed into it. Thanks in advance for any help regarding this matter.
Radu
Posts: 9041
Joined: Fri Jul 09, 2004 5:18 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by Radu »

Hi,

In the Oxygen main Tools menu there is an "XML Refactoring" action which shows various predefined refactoring actions. Each refactoring action can be applied on multiple files.
We do not have a predefined refactoring action for moving content but you can create your own XML refactoring actions based on XSLT or XQuery:

https://www.oxygenxml.com/doc/versions/ ... tools.html

As an example of what creating a refactoring action would imply for your precise use case:
1) Create somewhere on your disk a folder called for example "refactor".
2) In that folder create an XML file called "refactor.xml" with the content:

Code: Select all

<refactoringOperationDescriptor 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.oxygenxml.com/ns/xmlRefactoring" id="op_ltg_xvw_yhb" name="Move sequential list inside previous paragraph">
    <description>Move sequential list inside previous paragraph</description>    
    <script type="XSLT" href="refactor.xsl"/>
</refactoringOperationDescriptor>
3) In the same folder create a "refactor.xsl" XSLT stylesheet with the content:

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    
    <!-- Copy anything unchanged -->
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Copy template in a certaia mode -->
    <xsl:template match="node() | @*" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Match paragraphs preceding sequential lists -->
    <xsl:template match="*:para[following-sibling::*[1][local-name() = 'sequentialList']]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:apply-templates select="following-sibling::*[1][local-name() = 'sequentialList']" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Ignore outputting the sequential list because it will be output by the paragraph above it -->
    <xsl:template match="*:sequentialList[preceding-sibling::*[1][local-name() = 'para']]"/>
    
4) In the Oxygen Preferences->XML / XML Refactoring page add a reference to the "refactor" folder.
5) Use the Tools->XML refactoring action and you should find the new operation called Move sequential list inside previous paragraph in the list of available operations.
6) Apply the operation on the set of resources that you want to modify, there is a "Preview" button which you should use to check the operation does what you want.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
binar
Posts: 26
Joined: Wed Apr 10, 2019 7:43 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by binar »

Radu,
Thank you very much for your post. I am amazed OxygenXML has the capability to take on such a task. I don't think there is no other XML editor in the market that offers as much as OxygenXML offers in the way of capability.

Nevertheless, I created a "refactor.xml" and "refactor.xsl" file and both were placed in a "refactor" folder. For my project XML file I created a very basic Descriptive Data Module really only containing the code shown below as content to test out:

Code: Select all

<para>Parent Paragraph:</para><sequentialList>
<listItem><para>DATA 1</para></listItem>
<listItem><para>DATA 1</para></listItem>
<listItem><para>DATA 1</para></listItem>
<listItem><para>DATA 1</para></listItem>
<listItem><para>DATA 1</para></listItem>
<listItem><para>DATA 1</para></listItem>
</sequentialList>
Upon performing a XML Refactoring PREVIEW a window pops up with the message shown below:
"Could not find any resources that would be affected by this operation."

Would it be too much trouble for you to post a project XML file you have tested your XML Refactoring XSL code on so I can confirm I am not doing something wrong at my end?

Lastly, you use the term "certaia mode" as shown below. What does the term mean because Googling it did not give me any answer?

Code: Select all

<!-- Copy template in a certaia mode -->
From what I gather, the XSL file divides the work in the four phases shown below:

Code: Select all

<!-- Copy anything unchanged -->
<!-- Copy template in a certaia mode -->
<!-- Match paragraphs preceding sequential lists -->
<!-- Ignore outputting the sequential list because it will be output by the paragraph above it -->
In which of the four phases shown above is XQuery used?

Thank you very much for your help with this matter.
Radu
Posts: 9041
Joined: Fri Jul 09, 2004 5:18 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by Radu »

Hi,

Please find some answers below:
Upon performing a XML Refactoring PREVIEW a window pops up with the message shown below:
"Could not find any resources that would be affected by this operation."

Would it be too much trouble for you to post a project XML file you have tested your XML Refactoring XSL code on so I can confirm I am not doing something wrong at my end?
Sure, the XML I tested against looks like this:

Code: Select all

<root>
    <para>Parent Paragraph:</para><sequentialList>
        <listItem><para>DATA 1</para></listItem>
        <listItem><para>DATA 1</para></listItem>
        <listItem><para>DATA 1</para></listItem>
        <listItem><para>DATA 1</para></listItem>
        <listItem><para>DATA 1</para></listItem>
        <listItem><para>DATA 1</para></listItem>
    </sequentialList>
</root>
I opened the XML in the main editing area, when invoking the operation, in the "Scope and Filters" tab I chose "Current file".
Just make sure that in the "Scope and Filters" tab you select a scope in which your XML documents are included.
Lastly, you use the term "certaia mode" as shown below. What does the term mean because Googling it did not give me any answer?
That was just a typo. "certaia"=>"certain".
In which of the four phases shown above is XQuery used?
The custom refactoring script can be either XSLT or XQuery. As I'm comfortable with XSLT, I built it using XSLT.
You can find examples of XQuery scripts in the Oxygen refactoring folder (OXYGEN_INSTALL_DIR\refactoring\).

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
binar
Posts: 26
Joined: Wed Apr 10, 2019 7:43 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by binar »

Hi Radu,
Thank you very much for your post. I performed additional testing using your test XML file and I am still getting the same message as before. Obviously, I am doing something wrong. This time I am including screenshots to see if this will help you identify what I am doing wrong. Below is a step by step summary of how I am performing this XML Refactoring operation:

1) I created a "refactor" folder and inside of it I added your test XML file I named Radu and also included the refactor.xsl and refactor.xml files I created using the code you provided in your original post. Screenshot below shows all files and folder location:
Image

2) In my Oxygen Preferences->XML / XML Refactoring dialog window I created a reference to the "refactor" folder as shown below:
Image

3) I opened the Radu.xml file in the editing area as shown below:
Image

4) I select the Tools->XML Refactoring... menu selection as shown below:
Image


5) In the XML Refactoring dialog window I select the new operation called Move sequential list inside previous paragraph followed by clicking on the "Next" button shown below:
Image


6) On the XML Refactoring Scope and Filters dialog window I select the "Current File" radio button followed by clicking on the "Preview" button as shown below. Please note: I have the Radu.xml file opened in the Editing area so my understanding is this is within the scope of my "Current File" selection.
Image

7) The image below shows the "Could not find any resources that would be affected by this operation" message which appears shortly after clicking on the "Preview" button:
Image

8.) If I follow by clicking on the "Finish" button a "No resources were affected" message appears as shown below:
Image

That is a complete overview of how I am executing the steps and I have not been able to get pass the messages shown in steps 7 and 8. By the way, do you get the same error message I get shown in the log window that reads: "XML document structures must start and end within the same entry." ? I suspect that may be a possible problem. But then I do not see how, because I am using the same test file you are using and the same refactor.xsl and refactor.xml files you are using so that error message makes no sense to me.

From what I gather, XSL is a very complex skill to master because there is a lot to it. In your opinion, what XSL subject matter is the most useful to learn about first so an XSL newbie like me can get good at moving around different variations of XML blocks to different destinations in a XML file?

Lastly, I hope you can identify what I am doing wrong because I need to make my OxygenXML successfully perform this operation so I can do my work more efficiently. Again, thanks for your excellent support and I look forward to hearing back from you.
Radu
Posts: 9041
Joined: Fri Jul 09, 2004 5:18 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by Radu »

Hi,

Looking at the refactor.xsl content I posted, I forgot to post the last line in the file, it should be like this:

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    
    <!-- Copy anything unchanged -->
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Copy template in a certaia mode -->
    <xsl:template match="node() | @*" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Match paragraphs preceding sequential lists -->
    <xsl:template match="*:para[following-sibling::*[1][local-name() = 'sequentialList']]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:apply-templates select="following-sibling::*[1][local-name() = 'sequentialList']" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- Ignore outputting the sequential list because it will be output by the paragraph above it -->
    <xsl:template match="*:sequentialList[preceding-sibling::*[1][local-name() = 'para']]"/>
</xsl:stylesheet>
If this still will not work you can send me the 3 files via email (support@oxygenxml.com) and I can look into it.

About this remark:
From what I gather, XSL is a very complex skill to master because there is a lot to it. In your opinion, what XSL subject matter is the most useful to learn about first so an XSL newbie like me can get good at moving around different variations of XML blocks to different destinations in a XML file?
You can probably search online for XSLT tutorial. But the sample XSLT I gave you could also be useful, you can try to make various changes to it and adapt it for other particular move operations.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
binar
Posts: 26
Joined: Wed Apr 10, 2019 7:43 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by binar »

Radu,
Thank you very much for your excellent OxygenXML Editor support. I added the missing line of code to the XSL file and now it works perfectly as shown in the screen capture below. I was amazed how well it performed this XML block move operation.

Image


Additionally, in the previous operation we moved a <sequentialList> XML block that was located next door to the </para> tag it needed to be moved over to. For a different kind of XML block move operation I need to perform, how will your XSL file change for the kind of move operations I describe below in Examples #2, and 3? The <description> tag only appears once in the XML file. Given that, is it possible to move the Example #1 <referencedApplicGroup> XML block in front of the <description> tag as shown in Example #2? Alternatively, is it possible to move the same Example #1 <referencedApplicGroup> XML block after the <description> tag as shown in Example #3?

Compared to the previous <sequentialList> XML block move operation, this move operation is more complex because the <description> tag destination is farther away and not next door destination like it was in the <sequentialList> XML block move operation. If it is not too much trouble may you please post XSL coding examples that apply to Examples #2 and #3 shown below. I would be very grateful because it will help me a lot in understanding the capability of OxygenXML as it relates to moving XML blocks to destinations that are farther away. Thank you very much for your help.

Example #1: <referencedApplicGroup> XML block in original location.

Code: Select all

<dmodule>
<content>
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
	<referencedApplicGroup>
		<applic id="appl-001">
			<assert applicPropertyIdent="location-xyz" applicPropertyType="condition" applicPropertyValues="xyz" />
		</applic>
	</referencedApplicGroup>
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
	<description>
		<para></para>
	</description>
</content>
</dmodule>
Example #2: <referencedApplicGroup> XML block moved before description tag.

Code: Select all

<dmodule>
<content>
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
	<referencedApplicGroup>
		<applic id="appl-001">
			<assert applicPropertyIdent="location-xyz" applicPropertyType="condition" applicPropertyValues="xyz" />
		</applic>
	</referencedApplicGroup>
	<description>
		<para></para>
	</description>
</content>
</dmodule>
Example #3: <referencedApplicGroup> XML block moved after description tag.

Code: Select all

<dmodule>
<content>
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
		<xmldata>data</xmldata)
	<description>
	<referencedApplicGroup>
		<applic id="appl-001">
			<assert applicPropertyIdent="location-xyz" applicPropertyType="condition" applicPropertyValues="xyz" />
		</applic>
	</referencedApplicGroup>
		<para></para>
	</description>
</content>
</dmodule>
Radu
Posts: 9041
Joined: Fri Jul 09, 2004 5:18 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by Radu »

Hi,

For moving the "referencedApplicGroup" before "description" custom XML refactoring XSLT stylesheet would look like this:

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="node() | @*" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="referencedApplicGroup[following-sibling::description]">
        <!-- Ignore it, will be output before the description -->
    </xsl:template>
    
    <xsl:template match="description[preceding-sibling::referencedApplicGroup]">
        <xsl:apply-templates select="preceding-sibling::referencedApplicGroup" mode="copy"/>
        <xsl:apply-templates select="." mode="copy"/>
    </xsl:template>
</xsl:stylesheet>
I do not understand example 3, do you want to move "referencedApplicGroup" after "description", meaning that the XSLT stylesheet could be changed like this:

Code: Select all

  <xsl:template match="description[preceding-sibling::referencedApplicGroup]">
        <xsl:apply-templates select="." mode="copy"/>
        <xsl:apply-templates select="preceding-sibling::referencedApplicGroup" mode="copy"/>
    </xsl:template>
or inside the "description" meaning that the XSLT code would be changed something like:

Code: Select all

<xsl:template match="description[preceding-sibling::referencedApplicGroup]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="preceding-sibling::referencedApplicGroup" mode="copy"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
?

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
binar
Posts: 26
Joined: Wed Apr 10, 2019 7:43 pm

Re: Can OxygenXML batch relocate XML Blocks?

Post by binar »

Radu,
Thank you very much for all three of your XSL stylesheets. The first one performs a task I had to do manually not too long ago which was very tedious because it involved manually moving XML blocks at a location right before the opening tag of a designated element. Now I can rely on XML Refactoring to do it for me automatically. In short, this XSL template is the one that is most important to me and I plan to study it. The two other XSL template variations you included are great because they teach a lot when I compare them to the first main XSL template. But to answer your question you are correct with how you did Example #3. My objective was mainly to learn how the code changes with minor a minor difference in the destination location.

I am making some time to learn how to code my own XSL templates because I think it is an important skill to have in this line of work. Nevertheless, I want to thank you for the knowledge you have shared with me because it has opened my eyes to the power XSL has built into it.
Post Reply