I have xml document like below,
<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1">
<title>First chapter</title>
<section xml:id="section1">
<imageobject>
<image fileref="images/image1.jpg"/>
</imageobject>
<imageobject>
<image fileref="images/image2.jpg"/>
</imageobject>
</section>
<section xml:id="section2" xml:base="../other/section1.xml">
<imageobject>
<image fileref="images/image1.jpg"/>
</imageobject>
<imageobject>
<image fileref="images/image2.jpg"/>
</imageobject>
<section xml:id="section3" xml:base="../some-other/more/section3.xml">
<imageobject>
<image fileref="images/image1.jpg"/>
</imageobject>
</section>
</section>
<section xml:id="section4" xml:base="../some-other/section4.xml">
<imageobject>
<image fileref="images/image2.jpg"/>
</imageobject>
</section>
</chapter>
Be cause of same image name is repeated in different sections, I am renaming all image names other than first section using a java class. Then I can generate a list of renamed image names.
Now I want to reflect those changes in the above xml file also. As example when I rename “image1.jpg” to “aaa.jpg” in section2, I need to reflect that change in the my initial xml by generating a new xml with new renamed image names.
For that purpose, I am using Ant script which uses XSLT 1.0 and take my first xml and renamed image list as inputs and generate a new xml document with new fileref values. How I can make that XSLT and use it in my Ant script.
Here is my new renamed images list.
<Imagedata>
<section>
<sectionID>section2</sectionID>
<relativepath>images/aaa.jpg</relativepath>
<relativepath>images/bbb.jpg</relativepath>
</section>
<section>
<sectionID>section3</sectionID>
<relativepath>images/ccc.jpg</relativepath>
</section>
<section>
<sectionID>section4</sectionID>
<relativepath>images/ddd.jpg</relativepath>
</section>
</Imagedata>
And my new final xml will be some thing like,
<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1">
<title>First chapter</title>
<section xml:id="section1">
<imageobject>
<image fileref="images/image1.jpg"/>
</imageobject>
<imageobject>
<image fileref="images/image2.jpg"/>
</imageobject>
</section>
<section xml:id="section2" xml:base="../other/section1.xml">
<imageobject>
<image fileref="images/aaa.jpg"/>
</imageobject>
<imageobject>
<image fileref="images/bbb.jpg"/>
</imageobject>
<section xml:id="section3" xml:base="../some-other/more/section3.xml">
<imageobject>
<image fileref="images/ccc.jpg"/>
</imageobject>
</section>
</section>
<section xml:id="section4" xml:base="../some-other/section4.xml">
<imageobject>
<image fileref="images/ddd.jpg"/>
</imageobject>
</section>
</chapter>
Thank you..!!
Just for a quick demonstration, I have put the Imagedata document into a variable inside the stylesheet show below. In real use, you will pass in a parameter which is the URI of the Image data document, like so …
That aside, this XSLT 1.0 style-sheet…
…will transform your supplied input document to the expected output document.
Explanation
Consider the value-of expression in the last template. Starting from our matched fileref attribute, we navigate up until we get to section and get its id. This is given by the expression …
Then we take our look-up data and find the sectionID s. This is given by expression…
We need to cross-link these sections by section name. We achieve this by applying a predicate to the sectionID that its value must be the section value of the focus item. The predicate is here…
Now we have found the right lookup-section, we need to index into it by our current position of the focus item within the document-section. We calculate our position by counting the preceding siblings and adding one, like thus …
And thus the look-up replacement node, if it exists, is given by…
That’s all well and good when a replacement is in order, but there are cases where there is no co-responding lookup. In this case our attribute needs to retain its original value. We achieve this by an expression of the form …
If $something doesn’t exist (meaning it;s value is the empty sequence), then the above expression simply returns the focus item. If it does exist, then either the first item of $something will be returned or the focus item. Normally the union operator concatenates two sequences, de-dups and sorts in document order. But the two operands come from different documents, so there is no sorting nor de-duping going on. Thus the expression returns the replacement node when it exists, or if not then the focus item.