xslt-processor 4.3.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.mts +16 -4
- package/index.d.ts +16 -4
- package/index.js +188 -52
- package/index.js.map +1 -1
- package/index.mjs +188 -52
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/umd/xslt-processor.global.js +3 -3
- package/umd/xslt-processor.global.js.map +1 -1
package/index.d.mts
CHANGED
|
@@ -22,6 +22,7 @@ declare class XNode {
|
|
|
22
22
|
parentNode: XNode;
|
|
23
23
|
visited: boolean;
|
|
24
24
|
escape: boolean;
|
|
25
|
+
fromXslText: boolean;
|
|
25
26
|
static _unusedXNodes: any[];
|
|
26
27
|
constructor(type: number, name: string, opt_value: any, opt_owner: any, opt_namespace?: any);
|
|
27
28
|
/**
|
|
@@ -138,7 +139,7 @@ interface XPathNode {
|
|
|
138
139
|
nodeType: number;
|
|
139
140
|
nodeName: string;
|
|
140
141
|
localName?: string;
|
|
141
|
-
|
|
142
|
+
namespaceUri?: string | null;
|
|
142
143
|
textContent?: string | null;
|
|
143
144
|
parentNode?: XPathNode | null;
|
|
144
145
|
childNodes?: ArrayLike<XPathNode>;
|
|
@@ -532,7 +533,7 @@ type XsltOptions = {
|
|
|
532
533
|
cData: boolean;
|
|
533
534
|
escape: boolean;
|
|
534
535
|
selfClosingTags: boolean;
|
|
535
|
-
outputMethod?: 'xml' | 'html' | 'text' | 'xhtml' | 'json';
|
|
536
|
+
outputMethod?: 'xml' | 'html' | 'text' | 'xhtml' | 'json' | 'adaptive';
|
|
536
537
|
parameters?: XsltParameter[];
|
|
537
538
|
};
|
|
538
539
|
|
|
@@ -567,7 +568,7 @@ declare class Xslt {
|
|
|
567
568
|
options: XsltOptions;
|
|
568
569
|
decimalFormatSettings: XsltDecimalFormatSettings;
|
|
569
570
|
outputDocument: XDocument;
|
|
570
|
-
outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json';
|
|
571
|
+
outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json' | 'adaptive';
|
|
571
572
|
outputOmitXmlDeclaration: string;
|
|
572
573
|
version: string;
|
|
573
574
|
firstTemplateRan: boolean;
|
|
@@ -592,7 +593,7 @@ declare class Xslt {
|
|
|
592
593
|
* The exported entry point of the XSL-T processor.
|
|
593
594
|
* @param xmlDoc The input document root, as DOM node.
|
|
594
595
|
* @param stylesheet The stylesheet document root, as DOM node.
|
|
595
|
-
* @returns the processed document, as XML text in a string,
|
|
596
|
+
* @returns the processed document, as XML text in a string, JSON string if outputMethod is 'json', or text if outputMethod is 'text' or 'adaptive' (with text content).
|
|
596
597
|
*/
|
|
597
598
|
xsltProcess(xmlDoc: XDocument, stylesheet: XDocument): Promise<string>;
|
|
598
599
|
/**
|
|
@@ -843,6 +844,17 @@ declare class Xslt {
|
|
|
843
844
|
*/
|
|
844
845
|
protected xsltTemplate(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
845
846
|
protected xsltText(context: ExprContext, template: XNode, output?: XNode): void;
|
|
847
|
+
/**
|
|
848
|
+
* Validates XSLT stylesheet/transform attributes.
|
|
849
|
+
* According to XSLT specification, validates:
|
|
850
|
+
* - Required version attribute
|
|
851
|
+
* - Valid version values (1.0, 2.0, 3.0)
|
|
852
|
+
* - Valid namespace declarations
|
|
853
|
+
* - Valid values for optional attributes (extension-element-prefixes, exclude-result-prefixes)
|
|
854
|
+
* @param stylesheetElement The `<xsl:stylesheet>` or `<xsl:transform>` element to validate.
|
|
855
|
+
* @param context The Expression Context for namespace access.
|
|
856
|
+
*/
|
|
857
|
+
protected validateStylesheetAttributes(stylesheetElement: XNode, context: ExprContext): void;
|
|
846
858
|
/**
|
|
847
859
|
* Implements `<xsl:stylesheet>` and `<xsl:transform>`, and its corresponding
|
|
848
860
|
* validations.
|
package/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ declare class XNode {
|
|
|
22
22
|
parentNode: XNode;
|
|
23
23
|
visited: boolean;
|
|
24
24
|
escape: boolean;
|
|
25
|
+
fromXslText: boolean;
|
|
25
26
|
static _unusedXNodes: any[];
|
|
26
27
|
constructor(type: number, name: string, opt_value: any, opt_owner: any, opt_namespace?: any);
|
|
27
28
|
/**
|
|
@@ -138,7 +139,7 @@ interface XPathNode {
|
|
|
138
139
|
nodeType: number;
|
|
139
140
|
nodeName: string;
|
|
140
141
|
localName?: string;
|
|
141
|
-
|
|
142
|
+
namespaceUri?: string | null;
|
|
142
143
|
textContent?: string | null;
|
|
143
144
|
parentNode?: XPathNode | null;
|
|
144
145
|
childNodes?: ArrayLike<XPathNode>;
|
|
@@ -532,7 +533,7 @@ type XsltOptions = {
|
|
|
532
533
|
cData: boolean;
|
|
533
534
|
escape: boolean;
|
|
534
535
|
selfClosingTags: boolean;
|
|
535
|
-
outputMethod?: 'xml' | 'html' | 'text' | 'xhtml' | 'json';
|
|
536
|
+
outputMethod?: 'xml' | 'html' | 'text' | 'xhtml' | 'json' | 'adaptive';
|
|
536
537
|
parameters?: XsltParameter[];
|
|
537
538
|
};
|
|
538
539
|
|
|
@@ -567,7 +568,7 @@ declare class Xslt {
|
|
|
567
568
|
options: XsltOptions;
|
|
568
569
|
decimalFormatSettings: XsltDecimalFormatSettings;
|
|
569
570
|
outputDocument: XDocument;
|
|
570
|
-
outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json';
|
|
571
|
+
outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json' | 'adaptive';
|
|
571
572
|
outputOmitXmlDeclaration: string;
|
|
572
573
|
version: string;
|
|
573
574
|
firstTemplateRan: boolean;
|
|
@@ -592,7 +593,7 @@ declare class Xslt {
|
|
|
592
593
|
* The exported entry point of the XSL-T processor.
|
|
593
594
|
* @param xmlDoc The input document root, as DOM node.
|
|
594
595
|
* @param stylesheet The stylesheet document root, as DOM node.
|
|
595
|
-
* @returns the processed document, as XML text in a string,
|
|
596
|
+
* @returns the processed document, as XML text in a string, JSON string if outputMethod is 'json', or text if outputMethod is 'text' or 'adaptive' (with text content).
|
|
596
597
|
*/
|
|
597
598
|
xsltProcess(xmlDoc: XDocument, stylesheet: XDocument): Promise<string>;
|
|
598
599
|
/**
|
|
@@ -843,6 +844,17 @@ declare class Xslt {
|
|
|
843
844
|
*/
|
|
844
845
|
protected xsltTemplate(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
845
846
|
protected xsltText(context: ExprContext, template: XNode, output?: XNode): void;
|
|
847
|
+
/**
|
|
848
|
+
* Validates XSLT stylesheet/transform attributes.
|
|
849
|
+
* According to XSLT specification, validates:
|
|
850
|
+
* - Required version attribute
|
|
851
|
+
* - Valid version values (1.0, 2.0, 3.0)
|
|
852
|
+
* - Valid namespace declarations
|
|
853
|
+
* - Valid values for optional attributes (extension-element-prefixes, exclude-result-prefixes)
|
|
854
|
+
* @param stylesheetElement The `<xsl:stylesheet>` or `<xsl:transform>` element to validate.
|
|
855
|
+
* @param context The Expression Context for namespace access.
|
|
856
|
+
*/
|
|
857
|
+
protected validateStylesheetAttributes(stylesheetElement: XNode, context: ExprContext): void;
|
|
846
858
|
/**
|
|
847
859
|
* Implements `<xsl:stylesheet>` and `<xsl:transform>`, and its corresponding
|
|
848
860
|
* validations.
|
package/index.js
CHANGED
|
@@ -742,12 +742,12 @@ var XPathStep = class extends XPathExpression {
|
|
|
742
742
|
if (!nsUri) {
|
|
743
743
|
return false;
|
|
744
744
|
}
|
|
745
|
-
const
|
|
745
|
+
const nodeLocalName2 = node.localName || node.nodeName && this.extractLocalName(node.nodeName);
|
|
746
746
|
const nodeNsUri = node.namespaceURI || node.namespaceUri || "";
|
|
747
|
-
return
|
|
747
|
+
return nodeLocalName2 === localName && nodeNsUri === nsUri;
|
|
748
748
|
}
|
|
749
|
-
const
|
|
750
|
-
return
|
|
749
|
+
const nodeLocalName = node.localName || this.extractLocalName(node.nodeName);
|
|
750
|
+
return nodeLocalName === testName;
|
|
751
751
|
case "node-type":
|
|
752
752
|
switch (this.nodeTest.nodeType) {
|
|
753
753
|
case "node":
|
|
@@ -806,6 +806,17 @@ var XPathStep = class extends XPathExpression {
|
|
|
806
806
|
if (Array.isArray(value)) return value.length > 0;
|
|
807
807
|
return !!value;
|
|
808
808
|
}
|
|
809
|
+
/**
|
|
810
|
+
* Extract the local name from a qualified name (e.g., "ns:name" -> "name", "name" -> "name")
|
|
811
|
+
*/
|
|
812
|
+
extractLocalName(qname) {
|
|
813
|
+
if (!qname) return "";
|
|
814
|
+
const colonIndex = qname.indexOf(":");
|
|
815
|
+
if (colonIndex > 0) {
|
|
816
|
+
return qname.substring(colonIndex + 1);
|
|
817
|
+
}
|
|
818
|
+
return qname;
|
|
819
|
+
}
|
|
809
820
|
};
|
|
810
821
|
|
|
811
822
|
// src/xpath/lib/src/expressions/predicate-expression.ts
|
|
@@ -1090,7 +1101,7 @@ var XPathFunctionCall = class extends XPathExpression {
|
|
|
1090
1101
|
namespaceUri(args, context) {
|
|
1091
1102
|
var _a;
|
|
1092
1103
|
const node = this.getNodeArg(args, context);
|
|
1093
|
-
return (_a = node == null ? void 0 : node.
|
|
1104
|
+
return (_a = node == null ? void 0 : node.namespaceUri) != null ? _a : "";
|
|
1094
1105
|
}
|
|
1095
1106
|
nodeName(args, context) {
|
|
1096
1107
|
var _a;
|
|
@@ -1560,6 +1571,7 @@ var _XNode = class _XNode {
|
|
|
1560
1571
|
this.childNodes = [];
|
|
1561
1572
|
this.visited = false;
|
|
1562
1573
|
this.escape = true;
|
|
1574
|
+
this.fromXslText = false;
|
|
1563
1575
|
this.siblingPosition = -1;
|
|
1564
1576
|
this.init(type, name, opt_value, opt_owner, opt_namespace);
|
|
1565
1577
|
}
|
|
@@ -2086,23 +2098,32 @@ function xmlTransformedTextRecursive(node, buffer, options) {
|
|
|
2086
2098
|
const nodeType = node.nodeType;
|
|
2087
2099
|
const nodeValue = node.nodeValue;
|
|
2088
2100
|
if (nodeType === DOM_TEXT_NODE) {
|
|
2089
|
-
|
|
2101
|
+
const isFromXslText = node.fromXslText === true;
|
|
2102
|
+
if (node.nodeValue && (isFromXslText || node.nodeValue.trim() !== "")) {
|
|
2090
2103
|
const finalText = node.escape && options.escape ? xmlEscapeText(node.nodeValue) : xmlUnescapeText(node.nodeValue);
|
|
2091
2104
|
buffer.push(finalText);
|
|
2092
2105
|
}
|
|
2093
2106
|
} else if (nodeType === DOM_CDATA_SECTION_NODE) {
|
|
2094
|
-
if (options.
|
|
2107
|
+
if (options.outputMethod === "text") {
|
|
2108
|
+
buffer.push(nodeValue);
|
|
2109
|
+
} else if (options.cData) {
|
|
2095
2110
|
buffer.push(xmlEscapeText(nodeValue));
|
|
2096
2111
|
} else {
|
|
2097
2112
|
buffer.push(`<![CDATA[${nodeValue}]]>`);
|
|
2098
2113
|
}
|
|
2099
2114
|
} else if (nodeType == DOM_COMMENT_NODE) {
|
|
2100
|
-
|
|
2115
|
+
if (options.outputMethod !== "text") {
|
|
2116
|
+
buffer.push(`<!-- ${nodeValue} -->`);
|
|
2117
|
+
}
|
|
2101
2118
|
} else if (nodeType == DOM_ELEMENT_NODE) {
|
|
2102
|
-
if (
|
|
2103
|
-
|
|
2119
|
+
if (options.outputMethod === "text") {
|
|
2120
|
+
xmlElementLogicTextOnly(node, buffer, options);
|
|
2104
2121
|
} else {
|
|
2105
|
-
|
|
2122
|
+
if (node.nodeName !== null && node.nodeName !== void 0) {
|
|
2123
|
+
xmlElementLogicTrivial(node, buffer, options);
|
|
2124
|
+
} else {
|
|
2125
|
+
xmlElementLogicMuted(node, buffer, options);
|
|
2126
|
+
}
|
|
2106
2127
|
}
|
|
2107
2128
|
} else if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2108
2129
|
let childNodes = node.firstChild ? [] : node.childNodes;
|
|
@@ -2190,6 +2211,22 @@ function xmlElementLogicMuted(node, buffer, options) {
|
|
|
2190
2211
|
xmlTransformedTextRecursive(childNodes[i], buffer, options);
|
|
2191
2212
|
}
|
|
2192
2213
|
}
|
|
2214
|
+
function xmlElementLogicTextOnly(node, buffer, options) {
|
|
2215
|
+
let childNodes = [];
|
|
2216
|
+
if (node.firstChild) {
|
|
2217
|
+
let child = node.firstChild;
|
|
2218
|
+
while (child) {
|
|
2219
|
+
childNodes.push(child);
|
|
2220
|
+
child = child.nextSibling;
|
|
2221
|
+
}
|
|
2222
|
+
} else {
|
|
2223
|
+
childNodes = node.childNodes;
|
|
2224
|
+
}
|
|
2225
|
+
childNodes = childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);
|
|
2226
|
+
for (let i = 0; i < childNodes.length; ++i) {
|
|
2227
|
+
xmlTransformedTextRecursive(childNodes[i], buffer, options);
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2193
2230
|
function xmlFullNodeName(node) {
|
|
2194
2231
|
const nodeName = node.nodeName;
|
|
2195
2232
|
if (node.prefix && nodeName.indexOf(`${node.prefix}:`) != 0) {
|
|
@@ -2297,6 +2334,41 @@ function nodeToJsonObject(node) {
|
|
|
2297
2334
|
}
|
|
2298
2335
|
return null;
|
|
2299
2336
|
}
|
|
2337
|
+
function detectAdaptiveOutputFormat(node) {
|
|
2338
|
+
if (!node) {
|
|
2339
|
+
return "xml";
|
|
2340
|
+
}
|
|
2341
|
+
const nodeType = node.nodeType;
|
|
2342
|
+
if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2343
|
+
const children = node.childNodes || [];
|
|
2344
|
+
let elementCount = 0;
|
|
2345
|
+
let textCount = 0;
|
|
2346
|
+
let hasSignificantText = false;
|
|
2347
|
+
for (let i = 0; i < children.length; i++) {
|
|
2348
|
+
const child = children[i];
|
|
2349
|
+
if (child.nodeType === DOM_ELEMENT_NODE) {
|
|
2350
|
+
elementCount++;
|
|
2351
|
+
} else if (child.nodeType === DOM_TEXT_NODE) {
|
|
2352
|
+
const text = child.nodeValue ? child.nodeValue.trim() : "";
|
|
2353
|
+
if (text.length > 0) {
|
|
2354
|
+
textCount++;
|
|
2355
|
+
hasSignificantText = true;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
if (elementCount === 0 && hasSignificantText) {
|
|
2360
|
+
return "text";
|
|
2361
|
+
}
|
|
2362
|
+
return "xml";
|
|
2363
|
+
}
|
|
2364
|
+
if (nodeType === DOM_TEXT_NODE || nodeType === DOM_CDATA_SECTION_NODE) {
|
|
2365
|
+
const text = node.nodeValue ? node.nodeValue.trim() : "";
|
|
2366
|
+
if (text.length > 0) {
|
|
2367
|
+
return "text";
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return "xml";
|
|
2371
|
+
}
|
|
2300
2372
|
function xmlToJson(node) {
|
|
2301
2373
|
if (!node) {
|
|
2302
2374
|
return "{}";
|
|
@@ -2573,7 +2645,7 @@ var XmlParser = class {
|
|
|
2573
2645
|
} else if (!tag && char === "<") {
|
|
2574
2646
|
let text = xml.slice(start, i);
|
|
2575
2647
|
if (text && parent !== root) {
|
|
2576
|
-
domAppendChild(parent, domCreateTextNode(xmlDocument, text));
|
|
2648
|
+
domAppendChild(parent, domCreateTextNode(xmlDocument, import_he2.default.decode(text)));
|
|
2577
2649
|
}
|
|
2578
2650
|
if (xml.slice(i + 1, i + 4) === "!--") {
|
|
2579
2651
|
let endTagIndex = xml.slice(i + 4).indexOf("-->");
|
|
@@ -2717,15 +2789,6 @@ var NodeConverter = class {
|
|
|
2717
2789
|
adaptXNode(node) {
|
|
2718
2790
|
if (!node) return null;
|
|
2719
2791
|
const adapted = node;
|
|
2720
|
-
if (!("namespaceURI" in adapted)) {
|
|
2721
|
-
Object.defineProperty(adapted, "namespaceURI", {
|
|
2722
|
-
get() {
|
|
2723
|
-
return this.namespaceUri;
|
|
2724
|
-
},
|
|
2725
|
-
enumerable: true,
|
|
2726
|
-
configurable: true
|
|
2727
|
-
});
|
|
2728
|
-
}
|
|
2729
2792
|
if (!("textContent" in adapted)) {
|
|
2730
2793
|
Object.defineProperty(adapted, "textContent", {
|
|
2731
2794
|
get() {
|
|
@@ -3693,7 +3756,7 @@ var Xslt = class {
|
|
|
3693
3756
|
* The exported entry point of the XSL-T processor.
|
|
3694
3757
|
* @param xmlDoc The input document root, as DOM node.
|
|
3695
3758
|
* @param stylesheet The stylesheet document root, as DOM node.
|
|
3696
|
-
* @returns the processed document, as XML text in a string,
|
|
3759
|
+
* @returns the processed document, as XML text in a string, JSON string if outputMethod is 'json', or text if outputMethod is 'text' or 'adaptive' (with text content).
|
|
3697
3760
|
*/
|
|
3698
3761
|
xsltProcess(xmlDoc, stylesheet) {
|
|
3699
3762
|
return __async(this, null, function* () {
|
|
@@ -3709,11 +3772,15 @@ var Xslt = class {
|
|
|
3709
3772
|
if (this.outputMethod === "json") {
|
|
3710
3773
|
return xmlToJson(outputDocument);
|
|
3711
3774
|
}
|
|
3775
|
+
let outputMethod = this.outputMethod;
|
|
3776
|
+
if (this.outputMethod === "adaptive") {
|
|
3777
|
+
outputMethod = detectAdaptiveOutputFormat(outputDocument);
|
|
3778
|
+
}
|
|
3712
3779
|
const transformedOutputXml = xmlTransformedText(outputDocument, {
|
|
3713
3780
|
cData: this.options.cData,
|
|
3714
3781
|
escape: this.options.escape,
|
|
3715
3782
|
selfClosingTags: this.options.selfClosingTags,
|
|
3716
|
-
outputMethod
|
|
3783
|
+
outputMethod
|
|
3717
3784
|
});
|
|
3718
3785
|
return transformedOutputXml;
|
|
3719
3786
|
});
|
|
@@ -3874,6 +3941,9 @@ var Xslt = class {
|
|
|
3874
3941
|
for (let j = 0; j < modifiedContext.contextSize(); ++j) {
|
|
3875
3942
|
const currentNode = modifiedContext.nodeList[j];
|
|
3876
3943
|
if (currentNode.nodeType === DOM_TEXT_NODE) {
|
|
3944
|
+
if (!this.xsltPassText(currentNode)) {
|
|
3945
|
+
continue;
|
|
3946
|
+
}
|
|
3877
3947
|
const textNodeContext = context.clone(
|
|
3878
3948
|
[currentNode],
|
|
3879
3949
|
0
|
|
@@ -4642,6 +4712,7 @@ var Xslt = class {
|
|
|
4642
4712
|
xsltText(context, template, output) {
|
|
4643
4713
|
const text = xmlValue(template);
|
|
4644
4714
|
const node = domCreateTextNode(this.outputDocument, text);
|
|
4715
|
+
node.fromXslText = true;
|
|
4645
4716
|
const disableOutputEscaping = template.childNodes.filter(
|
|
4646
4717
|
(a) => a.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName === "disable-output-escaping"
|
|
4647
4718
|
);
|
|
@@ -4649,8 +4720,80 @@ var Xslt = class {
|
|
|
4649
4720
|
node.escape = false;
|
|
4650
4721
|
}
|
|
4651
4722
|
const destinationTextNode = output || this.outputDocument;
|
|
4723
|
+
node.siblingPosition = destinationTextNode.childNodes.length;
|
|
4652
4724
|
destinationTextNode.appendChild(node);
|
|
4653
4725
|
}
|
|
4726
|
+
/**
|
|
4727
|
+
* Validates XSLT stylesheet/transform attributes.
|
|
4728
|
+
* According to XSLT specification, validates:
|
|
4729
|
+
* - Required version attribute
|
|
4730
|
+
* - Valid version values (1.0, 2.0, 3.0)
|
|
4731
|
+
* - Valid namespace declarations
|
|
4732
|
+
* - Valid values for optional attributes (extension-element-prefixes, exclude-result-prefixes)
|
|
4733
|
+
* @param stylesheetElement The `<xsl:stylesheet>` or `<xsl:transform>` element to validate.
|
|
4734
|
+
* @param context The Expression Context for namespace access.
|
|
4735
|
+
*/
|
|
4736
|
+
validateStylesheetAttributes(stylesheetElement, context) {
|
|
4737
|
+
const attributes = stylesheetElement.childNodes.filter((n) => n.nodeType === DOM_ATTRIBUTE_NODE);
|
|
4738
|
+
const validAttributes = ["version", "id", "extension-element-prefixes", "exclude-result-prefixes", "default-collation"];
|
|
4739
|
+
const validNamespaceAttributes = ["xmlns"];
|
|
4740
|
+
let versionFound = false;
|
|
4741
|
+
for (let attribute of attributes) {
|
|
4742
|
+
const nodeName = attribute.nodeName;
|
|
4743
|
+
const nodeValue = attribute.nodeValue;
|
|
4744
|
+
if (attribute.prefix === "xmlns") {
|
|
4745
|
+
context.knownNamespaces[attribute.localName] = nodeValue;
|
|
4746
|
+
continue;
|
|
4747
|
+
}
|
|
4748
|
+
if (nodeName === "xmlns") {
|
|
4749
|
+
context.knownNamespaces[""] = nodeValue;
|
|
4750
|
+
continue;
|
|
4751
|
+
}
|
|
4752
|
+
if (nodeName === "version") {
|
|
4753
|
+
versionFound = true;
|
|
4754
|
+
if (!["1.0", "2.0", "3.0"].includes(nodeValue)) {
|
|
4755
|
+
throw new Error(
|
|
4756
|
+
`XSLT version not defined or invalid. Actual resolved version: ${nodeValue || "(none)"}.`
|
|
4757
|
+
);
|
|
4758
|
+
}
|
|
4759
|
+
this.version = nodeValue;
|
|
4760
|
+
context.xsltVersion = nodeValue;
|
|
4761
|
+
continue;
|
|
4762
|
+
}
|
|
4763
|
+
if (nodeName === "extension-element-prefixes") {
|
|
4764
|
+
const prefixes = nodeValue.split(/\s+/);
|
|
4765
|
+
for (const prefix of prefixes) {
|
|
4766
|
+
if (prefix && !/^[a-zA-Z_:][\w:.-]*$/.test(prefix)) {
|
|
4767
|
+
throw new Error(`Invalid prefix in extension-element-prefixes: "${prefix}". Prefixes must be valid QNames.`);
|
|
4768
|
+
}
|
|
4769
|
+
}
|
|
4770
|
+
continue;
|
|
4771
|
+
}
|
|
4772
|
+
if (nodeName === "exclude-result-prefixes") {
|
|
4773
|
+
if (nodeValue !== "#all") {
|
|
4774
|
+
const prefixes = nodeValue.split(/\s+/);
|
|
4775
|
+
for (const prefix of prefixes) {
|
|
4776
|
+
if (prefix && !/^[a-zA-Z_:][\w:.-]*$/.test(prefix)) {
|
|
4777
|
+
throw new Error(`Invalid prefix in exclude-result-prefixes: "${prefix}". Prefixes must be valid QNames or "#all".`);
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
}
|
|
4781
|
+
continue;
|
|
4782
|
+
}
|
|
4783
|
+
if (nodeName === "default-collation") {
|
|
4784
|
+
if (!nodeValue || nodeValue.trim().length === 0) {
|
|
4785
|
+
throw new Error("The default-collation attribute must contain a URI.");
|
|
4786
|
+
}
|
|
4787
|
+
continue;
|
|
4788
|
+
}
|
|
4789
|
+
if (nodeName === "id") {
|
|
4790
|
+
if (!/^[a-zA-Z_:][\w:.-]*$/.test(nodeValue)) {
|
|
4791
|
+
throw new Error(`Invalid id attribute value: "${nodeValue}". IDs must be valid NCNames.`);
|
|
4792
|
+
}
|
|
4793
|
+
continue;
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
}
|
|
4654
4797
|
/**
|
|
4655
4798
|
* Implements `<xsl:stylesheet>` and `<xsl:transform>`, and its corresponding
|
|
4656
4799
|
* validations.
|
|
@@ -4661,24 +4804,7 @@ var Xslt = class {
|
|
|
4661
4804
|
*/
|
|
4662
4805
|
xsltTransformOrStylesheet(context, template, output) {
|
|
4663
4806
|
return __async(this, null, function* () {
|
|
4664
|
-
|
|
4665
|
-
switch (stylesheetAttribute.nodeName) {
|
|
4666
|
-
case "version":
|
|
4667
|
-
this.version = stylesheetAttribute.nodeValue;
|
|
4668
|
-
if (!["1.0", "2.0", "3.0"].includes(this.version)) {
|
|
4669
|
-
throw new Error(
|
|
4670
|
-
`XSLT version not defined or invalid. Actual resolved version: ${this.version || "(none)"}.`
|
|
4671
|
-
);
|
|
4672
|
-
}
|
|
4673
|
-
context.xsltVersion = this.version;
|
|
4674
|
-
break;
|
|
4675
|
-
default:
|
|
4676
|
-
if (stylesheetAttribute.prefix === "xmlns") {
|
|
4677
|
-
context.knownNamespaces[stylesheetAttribute.localName] = stylesheetAttribute.nodeValue;
|
|
4678
|
-
}
|
|
4679
|
-
break;
|
|
4680
|
-
}
|
|
4681
|
-
}
|
|
4807
|
+
this.validateStylesheetAttributes(template, context);
|
|
4682
4808
|
let importsDone = false;
|
|
4683
4809
|
for (const child of template.childNodes) {
|
|
4684
4810
|
if (child.nodeType === DOM_ELEMENT_NODE) {
|
|
@@ -4718,16 +4844,22 @@ var Xslt = class {
|
|
|
4718
4844
|
}
|
|
4719
4845
|
}
|
|
4720
4846
|
if (matchCandidates.length > 0) {
|
|
4721
|
-
matchCandidates.
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4847
|
+
const rootPatternMatch = matchCandidates.find((c) => c.priority.matchPattern === "/");
|
|
4848
|
+
let winner;
|
|
4849
|
+
if (rootPatternMatch) {
|
|
4850
|
+
winner = rootPatternMatch;
|
|
4851
|
+
} else {
|
|
4852
|
+
matchCandidates.sort((a, b) => {
|
|
4853
|
+
if (a.priority.importPrecedence !== b.priority.importPrecedence) {
|
|
4854
|
+
return b.priority.importPrecedence - a.priority.importPrecedence;
|
|
4855
|
+
}
|
|
4856
|
+
if (a.priority.effectivePriority !== b.priority.effectivePriority) {
|
|
4857
|
+
return b.priority.effectivePriority - a.priority.effectivePriority;
|
|
4858
|
+
}
|
|
4859
|
+
return b.priority.documentOrder - a.priority.documentOrder;
|
|
4860
|
+
});
|
|
4861
|
+
winner = matchCandidates[0];
|
|
4862
|
+
}
|
|
4731
4863
|
const conflicts = matchCandidates.filter(
|
|
4732
4864
|
(t) => t.priority.importPrecedence === winner.priority.importPrecedence && t.priority.effectivePriority === winner.priority.effectivePriority
|
|
4733
4865
|
);
|
|
@@ -4865,7 +4997,11 @@ var Xslt = class {
|
|
|
4865
4997
|
return __async(this, null, function* () {
|
|
4866
4998
|
const contextClone = context.clone();
|
|
4867
4999
|
for (let i = 0; i < template.childNodes.length; ++i) {
|
|
4868
|
-
|
|
5000
|
+
const child = template.childNodes[i];
|
|
5001
|
+
if (child.nodeType === DOM_ATTRIBUTE_NODE) {
|
|
5002
|
+
continue;
|
|
5003
|
+
}
|
|
5004
|
+
yield this.xsltProcessContext(contextClone, child, output);
|
|
4869
5005
|
}
|
|
4870
5006
|
});
|
|
4871
5007
|
}
|