64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import type { TransformEngineId } from '../transform/transformTypes';
|
|
import { parseXmlDocument } from './xmlValidation';
|
|
import type { DiagnosticMessage } from './validationTypes';
|
|
|
|
const XSLT_NAMESPACE = 'http://www.w3.org/1999/XSL/Transform';
|
|
|
|
export function validateXslt(
|
|
text: string,
|
|
engine: TransformEngineId = 'native-xsltprocessor'
|
|
): DiagnosticMessage[] {
|
|
const { document: stylesheet, diagnostics } = parseXmlDocument(
|
|
text,
|
|
'XSLT stylesheet'
|
|
);
|
|
|
|
if (diagnostics.some((diagnostic) => diagnostic.severity === 'error')) {
|
|
return diagnostics;
|
|
}
|
|
|
|
const root = stylesheet.documentElement;
|
|
if (!root) {
|
|
return [
|
|
...diagnostics,
|
|
{
|
|
severity: 'error',
|
|
source: 'XSLT stylesheet',
|
|
message: 'The stylesheet has no document element.',
|
|
},
|
|
];
|
|
}
|
|
|
|
if (
|
|
root.namespaceURI !== XSLT_NAMESPACE ||
|
|
!['stylesheet', 'transform'].includes(root.localName)
|
|
) {
|
|
diagnostics.push({
|
|
severity: 'error',
|
|
source: 'XSLT stylesheet',
|
|
message:
|
|
'The root element should be xsl:stylesheet or xsl:transform in the XSLT namespace.',
|
|
});
|
|
}
|
|
|
|
const version = root.getAttribute('version');
|
|
if (!version) {
|
|
diagnostics.push({
|
|
severity: 'warning',
|
|
source: 'XSLT stylesheet',
|
|
message: 'The stylesheet root should declare a version attribute.',
|
|
});
|
|
}
|
|
|
|
if (engine === 'native-xsltprocessor' && version && version !== '1.0') {
|
|
diagnostics.push({
|
|
severity: 'warning',
|
|
source: 'XSLT stylesheet',
|
|
message:
|
|
'The native browser engine usually supports XSLT 1.0 only. XSLT 2.0/3.0 features may fail.',
|
|
});
|
|
}
|
|
|
|
return diagnostics;
|
|
}
|