Changing file extensions within a XML file
This one is a bit of a tricky one. I have a contents.xml file that references a host of other files. These other files use to be .xml, and have been altered to .dita, my question is how can i renames all the .xml file extensions to .dita? The file paths are a varying levels in the tree and have an inconsistent number of subfolders in front of them.
Example:<article
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Definition&开发者_Go百科lt;/title>
<xi:include href="./introduction.xml"/>
<section xml:id="viewComponents"><title>View Components</title>
<xi:include href="./components/page.xml"/>
<xi:include href="./views/sheet.xml"/>
<xi:include href="./folder/xsubfolders/plaque.xml"/>
</section>
</article>
To:
<article
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Definition</title>
<xi:include href="./introduction.dita"/>
<section xml:id="viewComponents"><title>View Components</title>
<xi:include href="./components/page.dita"/>
<xi:include href="./views/sheet.dita"/>
<xi:include href="./folder/xsubfolders/plaque.dita"/>
</section>
</article>
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"xi:include/@href[substring(., string-length()-3)='.xml']">
<xsl:attribute name="href">
<xsl:value-of select="concat(substring(.,1, string-length()-3),'dita')"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<article
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Definition</title>
<xi:include href="./introduction.xml"/>
<section xml:id="viewComponents"><title>View Components</title>
<xi:include href="./components/page.xml"/>
<xi:include href="./views/sheet.xml"/>
<xi:include href="./folder/xsubfolders/plaque.xml"/>
</section>
</article>
produces the wanted, correct result:
<article xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Definition</title>
<xi:include href="./introduction.dita"></xi:include>
<section xml:id="viewComponents">
<title>View Components</title>
<xi:include href="./components/page.dita"></xi:include>
<xi:include href="./views/sheet.dita"></xi:include>
<xi:include href="./folder/xsubfolders/plaque.dita"></xi:include>
</section>
</article>
You can do this with recursion:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*">
<xsl:choose>
<xsl:when test="substring(string(.), string-length(string(.)) - 3) = '.xml'">
<xsl:attribute name="{name()}">
<xsl:value-of select="concat(substring(string(.), 1, string-length(string(.)) - 4), '.dita')"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="{name()}"><xsl:value-of select="string(.)"/></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node()">
<xsl:copy><xsl:apply-templates select="./node()|./@*"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
The template at the bottom copies all input directly to the output, with the exception of attributes which are picked up by the template above, and the text transform is applied here.
精彩评论