I have a series of XML documents that are being copied from one folder into another, transformed with msxsl.exe 1.1.0.1 and an XSLT 1.0 stylesheet, then copied back to the original folder. I don't know why the doctype, entities and notations are not being copied over but currently they are being inserted with javascript in the style sheet. I have to replace the javascript with XSLT 3.0 so it will work with saxon HE11.
The doctype is the highest element in the XML, this is also my desired output:
<!DOCTYPE dmodule [
<!ENTITY ICN-XXX12-001-01 SYSTEM "ICN-XXX12-001-01.SWF" NDATA swf >
<!ENTITY ICN-XXX49-001-01 SYSTEM "ICN-XXX49-001-01 SYSTEM.CGM" NDATA cgm >
<!ENTITY ICN-AAA235-000000-0-A-001-01 SYSTEM "ICN-AAA235-000000-0-A-001-01.wrlzip" NDATA WRLZIP>
<!NOTATION cgm PUBLIC "-//USA-DOD//NOTATION Computer Graphics Metafile//EN" >
<!NOTATION swf PUBLIC "-//S1000D//NOTATION X-SHOCKWAVE-FLASH 3D Models Encoding//EN" >
<!NOTATION WRLZIP SYSTEM "WRLZIP">
]>
<dmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dc="http://www.purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:noNamespaceSchemaLocation="../schema/proced.xsd">
<content>
<figure>
<title/>
<graphic infoEntityIdent="ICN-XXX49-001-01"/>
</figure>
<proceduralStep>
<para>Check the brake system function.</para>
<multimedia>
<title>Brake function</title>
<multimediaObject autoPlay="1" fullScreen="0" infoEntityIdent="ICN-XXX12-001-01" multimediaType="other"/>
</multimedia>
</proceduralStep>
<multimedia>
<multimediaObject infoEntityIdent="ICN-AAA235-000000-0-A-001-01"
multimediaType="3D"
xlink:href="ICN-AAA235-000000-0-A-001-01.wrlzip"
xlink:type="simple"/>
</multimedia>
</content>
</dmodule>
The entities are referenced on @infoEntityIdent
from various elements but there is not always an indication of the type of file:
<graphic infoEntityIdent="ICN-XXX49-001-01"/>
<multimediaObject autoPlay="1" fullScreen="0" infoEntityIdent="ICN-XXX12-001-01"
multimediaType="other"/>
<multimediaObject infoEntityIdent="ICN-AAA235-000000-0-A-001-01"
multimediaType="3D" xlink:href="ICN-AAA235-000000-0-A-001-01.wrlzip"
xlink:type="simple"/>
I can get the doctype inserted correctly, but I don't know how to access the entities and notations:
<xsl:template match="/">
<xsl:text>
</xsl:text>
<xsl:text disable-output-escaping="yes"><!DOCTYPE </xsl:text>
<xsl:value-of select="local-name(child::*)"/>
<xsl:text> [</xsl:text>
<!-- entities and notations here -->
<xsl:text disable-output-escaping="yes">]></xsl:text>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
Current output:
<!DOCTYPE dmodule []>
<dmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dc="http://www.purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:noNamespaceSchemaLocation="../schema/proced.xsd">
<content>
<figure>
<title/>
<graphic infoEntityIdent="ICN-XXX49-001-01"/>
</figure>
<proceduralStep>
<para>Check the brake system function.</para>
<multimedia>
<title>Brake function</title>
<multimediaObject autoPlay="1" fullScreen="0" infoEntityIdent="ICN-XXX12-001-01" multimediaType="other"/>
</multimedia>
</proceduralStep>
<multimedia>
<multimediaObject infoEntityIdent="ICN-AAA235-000000-0-A-001-01"
multimediaType="3D"
xlink:href="ICN-AAA235-000000-0-A-001-01.wrlzip"
xlink:type="simple"/>
</multimedia>
</content>
This is the inherited javascript in the stylesheet, and it does give the desired result:
<msxsl:script language="JavaScript" implements-prefix="js">
<![CDATA[
function doctype(root) {
var fso = new ActiveXObject('Scripting.FileSystemObject');
var basepath = unescape(
root
.item(0)
.url
.replace(/^file:\/{3,}/, '')
.replace(/^file:/, '')
.replace(/[^\/]+$/, '')
.replace(/\//g, '\\')
);
var entities = [];
var notations = [];
var needSVGNotations = false;
if (root.item(0).doctype) {
entities = root.item(0).doctype.entities;
notations = root.item(0).doctype.notations;
}
var syntax = '\n<!DOCTYPE ' + root.item(0).documentElement.nodeName + ' [\n';
for (var i = 0; i < entities.length; i++) {
var entity = entities.item(i);
var s = entity.xml;
syntax += s + '\n';
}
for (var i = 0; i < notations.length; i++) {
var s = notations.item(i).xml;
syntax += s + '\n';
}
syntax += ']>\n';
return syntax;
}
]]>
</msxsl:script>
And this is the template using the javascript:
<xsl:template match="/">
<xsl:value-of select="js:doctype(.)" disable-output-escaping="yes"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>