xslt-processor 4.2.1 → 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/README.md +46 -1
- package/index.d.mts +16 -3
- package/index.d.ts +16 -3
- package/index.js +309 -53
- package/index.js.map +1 -1
- package/index.mjs +309 -53
- 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.mjs
CHANGED
|
@@ -706,12 +706,12 @@ var XPathStep = class extends XPathExpression {
|
|
|
706
706
|
if (!nsUri) {
|
|
707
707
|
return false;
|
|
708
708
|
}
|
|
709
|
-
const
|
|
709
|
+
const nodeLocalName2 = node.localName || node.nodeName && this.extractLocalName(node.nodeName);
|
|
710
710
|
const nodeNsUri = node.namespaceURI || node.namespaceUri || "";
|
|
711
|
-
return
|
|
711
|
+
return nodeLocalName2 === localName && nodeNsUri === nsUri;
|
|
712
712
|
}
|
|
713
|
-
const
|
|
714
|
-
return
|
|
713
|
+
const nodeLocalName = node.localName || this.extractLocalName(node.nodeName);
|
|
714
|
+
return nodeLocalName === testName;
|
|
715
715
|
case "node-type":
|
|
716
716
|
switch (this.nodeTest.nodeType) {
|
|
717
717
|
case "node":
|
|
@@ -770,6 +770,17 @@ var XPathStep = class extends XPathExpression {
|
|
|
770
770
|
if (Array.isArray(value)) return value.length > 0;
|
|
771
771
|
return !!value;
|
|
772
772
|
}
|
|
773
|
+
/**
|
|
774
|
+
* Extract the local name from a qualified name (e.g., "ns:name" -> "name", "name" -> "name")
|
|
775
|
+
*/
|
|
776
|
+
extractLocalName(qname) {
|
|
777
|
+
if (!qname) return "";
|
|
778
|
+
const colonIndex = qname.indexOf(":");
|
|
779
|
+
if (colonIndex > 0) {
|
|
780
|
+
return qname.substring(colonIndex + 1);
|
|
781
|
+
}
|
|
782
|
+
return qname;
|
|
783
|
+
}
|
|
773
784
|
};
|
|
774
785
|
|
|
775
786
|
// src/xpath/lib/src/expressions/predicate-expression.ts
|
|
@@ -1054,7 +1065,7 @@ var XPathFunctionCall = class extends XPathExpression {
|
|
|
1054
1065
|
namespaceUri(args, context) {
|
|
1055
1066
|
var _a;
|
|
1056
1067
|
const node = this.getNodeArg(args, context);
|
|
1057
|
-
return (_a = node == null ? void 0 : node.
|
|
1068
|
+
return (_a = node == null ? void 0 : node.namespaceUri) != null ? _a : "";
|
|
1058
1069
|
}
|
|
1059
1070
|
nodeName(args, context) {
|
|
1060
1071
|
var _a;
|
|
@@ -1524,6 +1535,7 @@ var _XNode = class _XNode {
|
|
|
1524
1535
|
this.childNodes = [];
|
|
1525
1536
|
this.visited = false;
|
|
1526
1537
|
this.escape = true;
|
|
1538
|
+
this.fromXslText = false;
|
|
1527
1539
|
this.siblingPosition = -1;
|
|
1528
1540
|
this.init(type, name, opt_value, opt_owner, opt_namespace);
|
|
1529
1541
|
}
|
|
@@ -2050,23 +2062,32 @@ function xmlTransformedTextRecursive(node, buffer, options) {
|
|
|
2050
2062
|
const nodeType = node.nodeType;
|
|
2051
2063
|
const nodeValue = node.nodeValue;
|
|
2052
2064
|
if (nodeType === DOM_TEXT_NODE) {
|
|
2053
|
-
|
|
2065
|
+
const isFromXslText = node.fromXslText === true;
|
|
2066
|
+
if (node.nodeValue && (isFromXslText || node.nodeValue.trim() !== "")) {
|
|
2054
2067
|
const finalText = node.escape && options.escape ? xmlEscapeText(node.nodeValue) : xmlUnescapeText(node.nodeValue);
|
|
2055
2068
|
buffer.push(finalText);
|
|
2056
2069
|
}
|
|
2057
2070
|
} else if (nodeType === DOM_CDATA_SECTION_NODE) {
|
|
2058
|
-
if (options.
|
|
2071
|
+
if (options.outputMethod === "text") {
|
|
2072
|
+
buffer.push(nodeValue);
|
|
2073
|
+
} else if (options.cData) {
|
|
2059
2074
|
buffer.push(xmlEscapeText(nodeValue));
|
|
2060
2075
|
} else {
|
|
2061
2076
|
buffer.push(`<![CDATA[${nodeValue}]]>`);
|
|
2062
2077
|
}
|
|
2063
2078
|
} else if (nodeType == DOM_COMMENT_NODE) {
|
|
2064
|
-
|
|
2079
|
+
if (options.outputMethod !== "text") {
|
|
2080
|
+
buffer.push(`<!-- ${nodeValue} -->`);
|
|
2081
|
+
}
|
|
2065
2082
|
} else if (nodeType == DOM_ELEMENT_NODE) {
|
|
2066
|
-
if (
|
|
2067
|
-
|
|
2083
|
+
if (options.outputMethod === "text") {
|
|
2084
|
+
xmlElementLogicTextOnly(node, buffer, options);
|
|
2068
2085
|
} else {
|
|
2069
|
-
|
|
2086
|
+
if (node.nodeName !== null && node.nodeName !== void 0) {
|
|
2087
|
+
xmlElementLogicTrivial(node, buffer, options);
|
|
2088
|
+
} else {
|
|
2089
|
+
xmlElementLogicMuted(node, buffer, options);
|
|
2090
|
+
}
|
|
2070
2091
|
}
|
|
2071
2092
|
} else if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2072
2093
|
let childNodes = node.firstChild ? [] : node.childNodes;
|
|
@@ -2154,6 +2175,22 @@ function xmlElementLogicMuted(node, buffer, options) {
|
|
|
2154
2175
|
xmlTransformedTextRecursive(childNodes[i], buffer, options);
|
|
2155
2176
|
}
|
|
2156
2177
|
}
|
|
2178
|
+
function xmlElementLogicTextOnly(node, buffer, options) {
|
|
2179
|
+
let childNodes = [];
|
|
2180
|
+
if (node.firstChild) {
|
|
2181
|
+
let child = node.firstChild;
|
|
2182
|
+
while (child) {
|
|
2183
|
+
childNodes.push(child);
|
|
2184
|
+
child = child.nextSibling;
|
|
2185
|
+
}
|
|
2186
|
+
} else {
|
|
2187
|
+
childNodes = node.childNodes;
|
|
2188
|
+
}
|
|
2189
|
+
childNodes = childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);
|
|
2190
|
+
for (let i = 0; i < childNodes.length; ++i) {
|
|
2191
|
+
xmlTransformedTextRecursive(childNodes[i], buffer, options);
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2157
2194
|
function xmlFullNodeName(node) {
|
|
2158
2195
|
const nodeName = node.nodeName;
|
|
2159
2196
|
if (node.prefix && nodeName.indexOf(`${node.prefix}:`) != 0) {
|
|
@@ -2177,6 +2214,157 @@ function xmlGetAttribute(node, name) {
|
|
|
2177
2214
|
}
|
|
2178
2215
|
return value;
|
|
2179
2216
|
}
|
|
2217
|
+
function nodeToJsonObject(node) {
|
|
2218
|
+
if (!node) {
|
|
2219
|
+
return null;
|
|
2220
|
+
}
|
|
2221
|
+
const nodeType = node.nodeType;
|
|
2222
|
+
if (nodeType === DOM_TEXT_NODE || nodeType === DOM_CDATA_SECTION_NODE) {
|
|
2223
|
+
const text = node.nodeValue ? node.nodeValue.trim() : "";
|
|
2224
|
+
return text.length > 0 ? text : null;
|
|
2225
|
+
}
|
|
2226
|
+
if (nodeType === DOM_COMMENT_NODE) {
|
|
2227
|
+
return null;
|
|
2228
|
+
}
|
|
2229
|
+
if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2230
|
+
const children = node.childNodes || [];
|
|
2231
|
+
const childObjects = [];
|
|
2232
|
+
for (let i = 0; i < children.length; i++) {
|
|
2233
|
+
const child = children[i];
|
|
2234
|
+
const childObj = nodeToJsonObject(child);
|
|
2235
|
+
if (childObj !== null) {
|
|
2236
|
+
childObjects.push(childObj);
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
if (childObjects.length === 0) {
|
|
2240
|
+
return null;
|
|
2241
|
+
} else if (childObjects.length === 1) {
|
|
2242
|
+
return childObjects[0];
|
|
2243
|
+
} else {
|
|
2244
|
+
return childObjects;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
if (nodeType === DOM_ELEMENT_NODE) {
|
|
2248
|
+
const obj = {};
|
|
2249
|
+
const element = node;
|
|
2250
|
+
const hasAttributes = element.attributes && element.attributes.length > 0;
|
|
2251
|
+
if (hasAttributes) {
|
|
2252
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
2253
|
+
const attr = element.attributes[i];
|
|
2254
|
+
obj["@" + attr.nodeName] = attr.nodeValue;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
const children = element.childNodes || [];
|
|
2258
|
+
let textContent = "";
|
|
2259
|
+
let hasElementChildren = false;
|
|
2260
|
+
const childElements = {};
|
|
2261
|
+
for (let i = 0; i < children.length; i++) {
|
|
2262
|
+
const child = children[i];
|
|
2263
|
+
const childType = child.nodeType;
|
|
2264
|
+
if (childType === DOM_TEXT_NODE || childType === DOM_CDATA_SECTION_NODE) {
|
|
2265
|
+
const text = child.nodeValue ? child.nodeValue.trim() : "";
|
|
2266
|
+
if (text.length > 0) {
|
|
2267
|
+
textContent += text;
|
|
2268
|
+
}
|
|
2269
|
+
} else if (childType === DOM_ELEMENT_NODE) {
|
|
2270
|
+
hasElementChildren = true;
|
|
2271
|
+
const childElement = child;
|
|
2272
|
+
const childName = childElement.localName || childElement.nodeName;
|
|
2273
|
+
const childObj = nodeToJsonObject(child);
|
|
2274
|
+
if (childObj !== null) {
|
|
2275
|
+
if (childElements[childName]) {
|
|
2276
|
+
if (!Array.isArray(childElements[childName])) {
|
|
2277
|
+
childElements[childName] = [childElements[childName]];
|
|
2278
|
+
}
|
|
2279
|
+
childElements[childName].push(childObj);
|
|
2280
|
+
} else {
|
|
2281
|
+
childElements[childName] = childObj;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
Object.assign(obj, childElements);
|
|
2287
|
+
if (!hasElementChildren && textContent.length > 0) {
|
|
2288
|
+
if (!hasAttributes && Object.keys(childElements).length === 0) {
|
|
2289
|
+
return textContent;
|
|
2290
|
+
} else {
|
|
2291
|
+
obj["#text"] = textContent;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (Object.keys(obj).length === 0) {
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
return obj;
|
|
2298
|
+
}
|
|
2299
|
+
return null;
|
|
2300
|
+
}
|
|
2301
|
+
function detectAdaptiveOutputFormat(node) {
|
|
2302
|
+
if (!node) {
|
|
2303
|
+
return "xml";
|
|
2304
|
+
}
|
|
2305
|
+
const nodeType = node.nodeType;
|
|
2306
|
+
if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2307
|
+
const children = node.childNodes || [];
|
|
2308
|
+
let elementCount = 0;
|
|
2309
|
+
let textCount = 0;
|
|
2310
|
+
let hasSignificantText = false;
|
|
2311
|
+
for (let i = 0; i < children.length; i++) {
|
|
2312
|
+
const child = children[i];
|
|
2313
|
+
if (child.nodeType === DOM_ELEMENT_NODE) {
|
|
2314
|
+
elementCount++;
|
|
2315
|
+
} else if (child.nodeType === DOM_TEXT_NODE) {
|
|
2316
|
+
const text = child.nodeValue ? child.nodeValue.trim() : "";
|
|
2317
|
+
if (text.length > 0) {
|
|
2318
|
+
textCount++;
|
|
2319
|
+
hasSignificantText = true;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
if (elementCount === 0 && hasSignificantText) {
|
|
2324
|
+
return "text";
|
|
2325
|
+
}
|
|
2326
|
+
return "xml";
|
|
2327
|
+
}
|
|
2328
|
+
if (nodeType === DOM_TEXT_NODE || nodeType === DOM_CDATA_SECTION_NODE) {
|
|
2329
|
+
const text = node.nodeValue ? node.nodeValue.trim() : "";
|
|
2330
|
+
if (text.length > 0) {
|
|
2331
|
+
return "text";
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
return "xml";
|
|
2335
|
+
}
|
|
2336
|
+
function xmlToJson(node) {
|
|
2337
|
+
if (!node) {
|
|
2338
|
+
return "{}";
|
|
2339
|
+
}
|
|
2340
|
+
let rootElement = node;
|
|
2341
|
+
if (node.nodeType === DOM_DOCUMENT_NODE || node.nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
|
|
2342
|
+
const children = node.childNodes || [];
|
|
2343
|
+
for (let i = 0; i < children.length; i++) {
|
|
2344
|
+
if (children[i].nodeType === DOM_ELEMENT_NODE) {
|
|
2345
|
+
rootElement = children[i];
|
|
2346
|
+
break;
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
const element = rootElement;
|
|
2351
|
+
const rootName = element.localName || element.nodeName;
|
|
2352
|
+
const jsonObj = {};
|
|
2353
|
+
const elementContent = nodeToJsonObject(rootElement);
|
|
2354
|
+
if (elementContent === null) {
|
|
2355
|
+
jsonObj[rootName] = {};
|
|
2356
|
+
} else if (typeof elementContent === "object" && !Array.isArray(elementContent)) {
|
|
2357
|
+
jsonObj[rootName] = elementContent;
|
|
2358
|
+
} else {
|
|
2359
|
+
jsonObj[rootName] = elementContent;
|
|
2360
|
+
}
|
|
2361
|
+
try {
|
|
2362
|
+
const cleaned = JSON.parse(JSON.stringify(jsonObj));
|
|
2363
|
+
return JSON.stringify(cleaned);
|
|
2364
|
+
} catch (error) {
|
|
2365
|
+
return JSON.stringify(jsonObj);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2180
2368
|
|
|
2181
2369
|
// src/dom/xml-parser.ts
|
|
2182
2370
|
import he2 from "he";
|
|
@@ -2421,7 +2609,7 @@ var XmlParser = class {
|
|
|
2421
2609
|
} else if (!tag && char === "<") {
|
|
2422
2610
|
let text = xml.slice(start, i);
|
|
2423
2611
|
if (text && parent !== root) {
|
|
2424
|
-
domAppendChild(parent, domCreateTextNode(xmlDocument, text));
|
|
2612
|
+
domAppendChild(parent, domCreateTextNode(xmlDocument, he2.decode(text)));
|
|
2425
2613
|
}
|
|
2426
2614
|
if (xml.slice(i + 1, i + 4) === "!--") {
|
|
2427
2615
|
let endTagIndex = xml.slice(i + 4).indexOf("-->");
|
|
@@ -2565,15 +2753,6 @@ var NodeConverter = class {
|
|
|
2565
2753
|
adaptXNode(node) {
|
|
2566
2754
|
if (!node) return null;
|
|
2567
2755
|
const adapted = node;
|
|
2568
|
-
if (!("namespaceURI" in adapted)) {
|
|
2569
|
-
Object.defineProperty(adapted, "namespaceURI", {
|
|
2570
|
-
get() {
|
|
2571
|
-
return this.namespaceUri;
|
|
2572
|
-
},
|
|
2573
|
-
enumerable: true,
|
|
2574
|
-
configurable: true
|
|
2575
|
-
});
|
|
2576
|
-
}
|
|
2577
2756
|
if (!("textContent" in adapted)) {
|
|
2578
2757
|
Object.defineProperty(adapted, "textContent", {
|
|
2579
2758
|
get() {
|
|
@@ -3515,9 +3694,10 @@ var Xslt = class {
|
|
|
3515
3694
|
cData: options.cData === true,
|
|
3516
3695
|
escape: options.escape === true,
|
|
3517
3696
|
selfClosingTags: options.selfClosingTags === true,
|
|
3697
|
+
outputMethod: options.outputMethod,
|
|
3518
3698
|
parameters: options.parameters || []
|
|
3519
3699
|
};
|
|
3520
|
-
this.outputMethod = "xml";
|
|
3700
|
+
this.outputMethod = options.outputMethod || "xml";
|
|
3521
3701
|
this.outputOmitXmlDeclaration = "no";
|
|
3522
3702
|
this.stripSpacePatterns = [];
|
|
3523
3703
|
this.preserveSpacePatterns = [];
|
|
@@ -3540,7 +3720,7 @@ var Xslt = class {
|
|
|
3540
3720
|
* The exported entry point of the XSL-T processor.
|
|
3541
3721
|
* @param xmlDoc The input document root, as DOM node.
|
|
3542
3722
|
* @param stylesheet The stylesheet document root, as DOM node.
|
|
3543
|
-
* @returns the processed document, as XML text in a string.
|
|
3723
|
+
* @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).
|
|
3544
3724
|
*/
|
|
3545
3725
|
xsltProcess(xmlDoc, stylesheet) {
|
|
3546
3726
|
return __async(this, null, function* () {
|
|
@@ -3553,11 +3733,18 @@ var Xslt = class {
|
|
|
3553
3733
|
}
|
|
3554
3734
|
}
|
|
3555
3735
|
yield this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);
|
|
3736
|
+
if (this.outputMethod === "json") {
|
|
3737
|
+
return xmlToJson(outputDocument);
|
|
3738
|
+
}
|
|
3739
|
+
let outputMethod = this.outputMethod;
|
|
3740
|
+
if (this.outputMethod === "adaptive") {
|
|
3741
|
+
outputMethod = detectAdaptiveOutputFormat(outputDocument);
|
|
3742
|
+
}
|
|
3556
3743
|
const transformedOutputXml = xmlTransformedText(outputDocument, {
|
|
3557
3744
|
cData: this.options.cData,
|
|
3558
3745
|
escape: this.options.escape,
|
|
3559
3746
|
selfClosingTags: this.options.selfClosingTags,
|
|
3560
|
-
outputMethod
|
|
3747
|
+
outputMethod
|
|
3561
3748
|
});
|
|
3562
3749
|
return transformedOutputXml;
|
|
3563
3750
|
});
|
|
@@ -3718,6 +3905,9 @@ var Xslt = class {
|
|
|
3718
3905
|
for (let j = 0; j < modifiedContext.contextSize(); ++j) {
|
|
3719
3906
|
const currentNode = modifiedContext.nodeList[j];
|
|
3720
3907
|
if (currentNode.nodeType === DOM_TEXT_NODE) {
|
|
3908
|
+
if (!this.xsltPassText(currentNode)) {
|
|
3909
|
+
continue;
|
|
3910
|
+
}
|
|
3721
3911
|
const textNodeContext = context.clone(
|
|
3722
3912
|
[currentNode],
|
|
3723
3913
|
0
|
|
@@ -4486,6 +4676,7 @@ var Xslt = class {
|
|
|
4486
4676
|
xsltText(context, template, output) {
|
|
4487
4677
|
const text = xmlValue(template);
|
|
4488
4678
|
const node = domCreateTextNode(this.outputDocument, text);
|
|
4679
|
+
node.fromXslText = true;
|
|
4489
4680
|
const disableOutputEscaping = template.childNodes.filter(
|
|
4490
4681
|
(a) => a.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName === "disable-output-escaping"
|
|
4491
4682
|
);
|
|
@@ -4493,8 +4684,80 @@ var Xslt = class {
|
|
|
4493
4684
|
node.escape = false;
|
|
4494
4685
|
}
|
|
4495
4686
|
const destinationTextNode = output || this.outputDocument;
|
|
4687
|
+
node.siblingPosition = destinationTextNode.childNodes.length;
|
|
4496
4688
|
destinationTextNode.appendChild(node);
|
|
4497
4689
|
}
|
|
4690
|
+
/**
|
|
4691
|
+
* Validates XSLT stylesheet/transform attributes.
|
|
4692
|
+
* According to XSLT specification, validates:
|
|
4693
|
+
* - Required version attribute
|
|
4694
|
+
* - Valid version values (1.0, 2.0, 3.0)
|
|
4695
|
+
* - Valid namespace declarations
|
|
4696
|
+
* - Valid values for optional attributes (extension-element-prefixes, exclude-result-prefixes)
|
|
4697
|
+
* @param stylesheetElement The `<xsl:stylesheet>` or `<xsl:transform>` element to validate.
|
|
4698
|
+
* @param context The Expression Context for namespace access.
|
|
4699
|
+
*/
|
|
4700
|
+
validateStylesheetAttributes(stylesheetElement, context) {
|
|
4701
|
+
const attributes = stylesheetElement.childNodes.filter((n) => n.nodeType === DOM_ATTRIBUTE_NODE);
|
|
4702
|
+
const validAttributes = ["version", "id", "extension-element-prefixes", "exclude-result-prefixes", "default-collation"];
|
|
4703
|
+
const validNamespaceAttributes = ["xmlns"];
|
|
4704
|
+
let versionFound = false;
|
|
4705
|
+
for (let attribute of attributes) {
|
|
4706
|
+
const nodeName = attribute.nodeName;
|
|
4707
|
+
const nodeValue = attribute.nodeValue;
|
|
4708
|
+
if (attribute.prefix === "xmlns") {
|
|
4709
|
+
context.knownNamespaces[attribute.localName] = nodeValue;
|
|
4710
|
+
continue;
|
|
4711
|
+
}
|
|
4712
|
+
if (nodeName === "xmlns") {
|
|
4713
|
+
context.knownNamespaces[""] = nodeValue;
|
|
4714
|
+
continue;
|
|
4715
|
+
}
|
|
4716
|
+
if (nodeName === "version") {
|
|
4717
|
+
versionFound = true;
|
|
4718
|
+
if (!["1.0", "2.0", "3.0"].includes(nodeValue)) {
|
|
4719
|
+
throw new Error(
|
|
4720
|
+
`XSLT version not defined or invalid. Actual resolved version: ${nodeValue || "(none)"}.`
|
|
4721
|
+
);
|
|
4722
|
+
}
|
|
4723
|
+
this.version = nodeValue;
|
|
4724
|
+
context.xsltVersion = nodeValue;
|
|
4725
|
+
continue;
|
|
4726
|
+
}
|
|
4727
|
+
if (nodeName === "extension-element-prefixes") {
|
|
4728
|
+
const prefixes = nodeValue.split(/\s+/);
|
|
4729
|
+
for (const prefix of prefixes) {
|
|
4730
|
+
if (prefix && !/^[a-zA-Z_:][\w:.-]*$/.test(prefix)) {
|
|
4731
|
+
throw new Error(`Invalid prefix in extension-element-prefixes: "${prefix}". Prefixes must be valid QNames.`);
|
|
4732
|
+
}
|
|
4733
|
+
}
|
|
4734
|
+
continue;
|
|
4735
|
+
}
|
|
4736
|
+
if (nodeName === "exclude-result-prefixes") {
|
|
4737
|
+
if (nodeValue !== "#all") {
|
|
4738
|
+
const prefixes = nodeValue.split(/\s+/);
|
|
4739
|
+
for (const prefix of prefixes) {
|
|
4740
|
+
if (prefix && !/^[a-zA-Z_:][\w:.-]*$/.test(prefix)) {
|
|
4741
|
+
throw new Error(`Invalid prefix in exclude-result-prefixes: "${prefix}". Prefixes must be valid QNames or "#all".`);
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
continue;
|
|
4746
|
+
}
|
|
4747
|
+
if (nodeName === "default-collation") {
|
|
4748
|
+
if (!nodeValue || nodeValue.trim().length === 0) {
|
|
4749
|
+
throw new Error("The default-collation attribute must contain a URI.");
|
|
4750
|
+
}
|
|
4751
|
+
continue;
|
|
4752
|
+
}
|
|
4753
|
+
if (nodeName === "id") {
|
|
4754
|
+
if (!/^[a-zA-Z_:][\w:.-]*$/.test(nodeValue)) {
|
|
4755
|
+
throw new Error(`Invalid id attribute value: "${nodeValue}". IDs must be valid NCNames.`);
|
|
4756
|
+
}
|
|
4757
|
+
continue;
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4498
4761
|
/**
|
|
4499
4762
|
* Implements `<xsl:stylesheet>` and `<xsl:transform>`, and its corresponding
|
|
4500
4763
|
* validations.
|
|
@@ -4505,24 +4768,7 @@ var Xslt = class {
|
|
|
4505
4768
|
*/
|
|
4506
4769
|
xsltTransformOrStylesheet(context, template, output) {
|
|
4507
4770
|
return __async(this, null, function* () {
|
|
4508
|
-
|
|
4509
|
-
switch (stylesheetAttribute.nodeName) {
|
|
4510
|
-
case "version":
|
|
4511
|
-
this.version = stylesheetAttribute.nodeValue;
|
|
4512
|
-
if (!["1.0", "2.0", "3.0"].includes(this.version)) {
|
|
4513
|
-
throw new Error(
|
|
4514
|
-
`XSLT version not defined or invalid. Actual resolved version: ${this.version || "(none)"}.`
|
|
4515
|
-
);
|
|
4516
|
-
}
|
|
4517
|
-
context.xsltVersion = this.version;
|
|
4518
|
-
break;
|
|
4519
|
-
default:
|
|
4520
|
-
if (stylesheetAttribute.prefix === "xmlns") {
|
|
4521
|
-
context.knownNamespaces[stylesheetAttribute.localName] = stylesheetAttribute.nodeValue;
|
|
4522
|
-
}
|
|
4523
|
-
break;
|
|
4524
|
-
}
|
|
4525
|
-
}
|
|
4771
|
+
this.validateStylesheetAttributes(template, context);
|
|
4526
4772
|
let importsDone = false;
|
|
4527
4773
|
for (const child of template.childNodes) {
|
|
4528
4774
|
if (child.nodeType === DOM_ELEMENT_NODE) {
|
|
@@ -4562,16 +4808,22 @@ var Xslt = class {
|
|
|
4562
4808
|
}
|
|
4563
4809
|
}
|
|
4564
4810
|
if (matchCandidates.length > 0) {
|
|
4565
|
-
matchCandidates.
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4811
|
+
const rootPatternMatch = matchCandidates.find((c) => c.priority.matchPattern === "/");
|
|
4812
|
+
let winner;
|
|
4813
|
+
if (rootPatternMatch) {
|
|
4814
|
+
winner = rootPatternMatch;
|
|
4815
|
+
} else {
|
|
4816
|
+
matchCandidates.sort((a, b) => {
|
|
4817
|
+
if (a.priority.importPrecedence !== b.priority.importPrecedence) {
|
|
4818
|
+
return b.priority.importPrecedence - a.priority.importPrecedence;
|
|
4819
|
+
}
|
|
4820
|
+
if (a.priority.effectivePriority !== b.priority.effectivePriority) {
|
|
4821
|
+
return b.priority.effectivePriority - a.priority.effectivePriority;
|
|
4822
|
+
}
|
|
4823
|
+
return b.priority.documentOrder - a.priority.documentOrder;
|
|
4824
|
+
});
|
|
4825
|
+
winner = matchCandidates[0];
|
|
4826
|
+
}
|
|
4575
4827
|
const conflicts = matchCandidates.filter(
|
|
4576
4828
|
(t) => t.priority.importPrecedence === winner.priority.importPrecedence && t.priority.effectivePriority === winner.priority.effectivePriority
|
|
4577
4829
|
);
|
|
@@ -4709,7 +4961,11 @@ var Xslt = class {
|
|
|
4709
4961
|
return __async(this, null, function* () {
|
|
4710
4962
|
const contextClone = context.clone();
|
|
4711
4963
|
for (let i = 0; i < template.childNodes.length; ++i) {
|
|
4712
|
-
|
|
4964
|
+
const child = template.childNodes[i];
|
|
4965
|
+
if (child.nodeType === DOM_ATTRIBUTE_NODE) {
|
|
4966
|
+
continue;
|
|
4967
|
+
}
|
|
4968
|
+
yield this.xsltProcessContext(contextClone, child, output);
|
|
4713
4969
|
}
|
|
4714
4970
|
});
|
|
4715
4971
|
}
|