Reputation: 33
I have an XML file that contains several elements named FileName1, FileName2, FileName3, and so on. I need to check the document for these element names and then rename them "FileName".
Here's the XML:
<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
<Transformed>
<ConnectionZone>Internal</ConnectionZone>
<Directory>/Test/Inbox</Directory>
<FTPProfileID>XYZ</FTPProfileID>
<FileName1>Test1.txt</FileName1>
<FileName2>Test2.txt</FileName2>
<MoveDirectory>/Test/MovedFiles</MoveDirectory>
<Operation>MV</Operation>
<RenameExt>.csv</RenameExt>
</Transformed>
</ProcessData>
Here's what I have in the XSLT so far:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<table>
<xsl:if test="//*[contains(name(), 'FileName']">
<xsl:element name="FileName">
</xsl:if>
</table>
</xsl:template>
</xsl:stylesheet>
Nothing I try has proven successful so far. I can't seem to get any matches in my xsl:if statement.
Please let me know if you can think of a better way to perform this! I just need to remove the last character (digit) of each element name that contains "FileName".
Thanks!
Upvotes: 0
Views: 2568
Reputation: 163524
Just to expand on Martin's answer, you have a classic transformation pattern where you want to copy everything unchanged except for a few things that you want to change. The solution to such problems is always: write an identity template rule that matches everything and copies it unchanged (Martin's second rule), and then write specific template rules that match the things you want to change, which in this case is any element whose name starts with "FileName".
By default the transformation will simply work its way down the tree matching elements and firing off template rules as it goes. So long as each template rule invokes xsl:apply-templates to process the children of the current element, every element in the document will be matched and will be processed as directed in the best matching template rule for that element.
Upvotes: 0
Reputation: 167706
You only need to write a template for those elements with
<xsl:template match="*[starts-with(local-name(), 'FileName')]">
<FileName>
<xsl:apply-templates/>
</FileName>
</xsl:template>
and of course include the identity transformation template
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:template>
</xsl:template>
as the main tool to keep processing the rest.
Upvotes: 0