I'm trying to use XSLT to update an XML document that I have. It needs to make multiple changes to the document to convert it to some other specifications.
What I want to do is update the same node more than once. Another way to look at it is I'd like to make multiple passes at the document, and each pass could update the same node.
All of my googling hints at using the 'mode' attribute of xsl:template, but all of the examples of the 'mode' attribute involve outputting the node twice - like in the case of using a heading in the table of contents and using it again as the title of a chapter. I don't want to output the node twice, I want to update it twice.
My sample XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version = '2.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<!-- identity transform (copy over the document) -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- wrap all BBB nodes in parenthesis -->
<xsl:template match="BBB" >
<xsl:copy>
(<xsl:apply-templates select="@*|node()" />)
</xsl:copy>
</xsl:template>
<!-- any BBB that has a CCC should get an attribute indicating so -->
<xsl:template match="BBB[CCC]">
<xsl:copy>
<xsl:attribute name="hasC">true</xsl:attribute>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
My sample xml document:
<?xml version="1.0" encoding="UTF-8"?>
<source>
<AAA>
<BBB>Bee bee bee</BBB>
<BBB>Bee two bee two bee two</BBB>
</AAA>
<AAA>
<BBB/>
<CCC>
<DDD/>
</CCC>
<BBB>
<CCC/>
</BBB>
</AAA>
</source>
The current output:
<?xml version="1.0" encoding="UTF-8"?><source>
<AAA>
<BBB>
(Bee bee bee)
</BBB>
<BBB>
(Bee two bee two bee two)
</BBB>
</AAA>
<AAA>
<BBB>
()
</BBB>
<CCC>
<DDD/>
</CCC>
<BBB hasC="true">
<CCC/>
</BBB>
</AAA>
</source>
As you can see, the BBB node that has the 'CCC' only got updated once, with the second template - the first template didn't modify it. Ideally, I want the output to be
<BBB hasC="true">
(<CCC/>)
</BBB>
Is this possible? I know I could accomplish this by combining the two templates together, but I really want to keep them separate for readability and maintinence - the two templates come from different requirements, and keeping them separate is ideal.
I suppose I could have two XSLT files and chain them together by calling the XSLT processor twice, but I'm hoping I don't need to that.
EDIT: Based on a lot of the comments I'm getting I think I am misunderstanding something fundamental about XSLT and transformations.
The problem I have is: I have a bunch of XML documents that conform to a spec. This specification has been updated by another group of people, so I need to create a batch/scriptable process to be able to update a large number of these XML documents so that they match this new spec.
Some of these new updates are things like the following.
1) <string lang="FR">hello</string>
needs to change to <string lang="fra">hello</string>
2) <a><b><string>Color</string><b></a>
needs to change to <a><b><string>Colour</string></b></a>
, but don't touch <a><c><string>Color</string></c></a>
3) all <orgName><string>***anytext***</string></orgName>
need to change to <orgName><string>My Company: ***anytext***</string></orgName>
4) all <orgName><string></string></orgName>
nodes need to change to <organisationName><string></string></orgisationName>
And so on. There are a lot of specific updates that could apply to the same nodes multiple times and there are enough of these updates that making multiple passes to the files seems like a better idea then creating one catch-all template that merges all of these updates into one large template.
Should I be using XSLT to try to do this? Is this a case where I need to break these changes up into multiple files and chain them in a script? Could I do all of these updates in a single .xslt file?