xslt-processor 4.8.5 → 5.0.0

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.js CHANGED
@@ -7800,9 +7800,12 @@ var init_expressions = __esm({
7800
7800
  var index_exports = {};
7801
7801
  __export(index_exports, {
7802
7802
  ExprContext: () => ExprContext,
7803
+ XDocument: () => XDocument,
7804
+ XNode: () => XNode,
7803
7805
  XPath: () => XPath,
7804
7806
  XmlParser: () => XmlParser,
7805
7807
  Xslt: () => Xslt,
7808
+ domDocumentToXDocument: () => domDocumentToXDocument,
7806
7809
  xmlEscapeText: () => xmlEscapeText
7807
7810
  });
7808
7811
  module.exports = __toCommonJS(index_exports);
@@ -10279,38 +10282,6 @@ function createXPathParser(version = DEFAULT_XPATH_VERSION, options) {
10279
10282
  // src/xpath/xpath.ts
10280
10283
  init_expressions();
10281
10284
 
10282
- // src/dom/functions.ts
10283
- function domGetAttributeValue(node, name) {
10284
- return node.getAttributeValue(name);
10285
- }
10286
- function domSetAttribute(node, name, value) {
10287
- return node.setAttribute(name, value);
10288
- }
10289
- function domAppendChild(node, child) {
10290
- return node.appendChild(child);
10291
- }
10292
- function domCreateTextNode(node, text) {
10293
- return node.createTextNode(text);
10294
- }
10295
- function domCreateElement(doc, name) {
10296
- return doc.createElement(name);
10297
- }
10298
- function domCreateCDATASection(doc, data2) {
10299
- return doc.createCDATASection(data2);
10300
- }
10301
- function domCreateComment(doc, text) {
10302
- return doc.createComment(text);
10303
- }
10304
- function domCreateDocumentFragment(doc) {
10305
- return doc.createDocumentFragment();
10306
- }
10307
- function domCreateDTDSection(doc, data2) {
10308
- return doc.createDTDSection(data2);
10309
- }
10310
- function domCreateProcessingInstruction(doc, target, data2) {
10311
- return doc.createProcessingInstruction(target, data2);
10312
- }
10313
-
10314
10285
  // src/constants.ts
10315
10286
  var DOM_ELEMENT_NODE = 1;
10316
10287
  var DOM_ATTRIBUTE_NODE = 2;
@@ -10735,7 +10706,9 @@ var XDocument = class extends XNode {
10735
10706
  }
10736
10707
  appendChild(node) {
10737
10708
  super.appendChild(node);
10738
- this.documentElement = this.childNodes[0];
10709
+ if (node.nodeType === DOM_ELEMENT_NODE && !this.documentElement) {
10710
+ this.documentElement = node;
10711
+ }
10739
10712
  }
10740
10713
  createElement(name) {
10741
10714
  return XNode.create(DOM_ELEMENT_NODE, name, null, this);
@@ -10769,6 +10742,130 @@ var XDocument = class extends XNode {
10769
10742
  }
10770
10743
  };
10771
10744
 
10745
+ // src/dom/dom-to-xdocument.ts
10746
+ function domDocumentToXDocument(nativeNode) {
10747
+ if (nativeNode.nodeType === DOM_DOCUMENT_NODE) {
10748
+ const xDoc2 = new XDocument();
10749
+ const childNodes = nativeNode.childNodes;
10750
+ for (let i = 0; i < childNodes.length; i++) {
10751
+ const converted2 = convertNode(childNodes[i], xDoc2);
10752
+ if (converted2) {
10753
+ converted2.siblingPosition = xDoc2.childNodes.length;
10754
+ xDoc2.appendChild(converted2);
10755
+ }
10756
+ }
10757
+ return xDoc2;
10758
+ }
10759
+ const xDoc = new XDocument();
10760
+ const converted = convertNode(nativeNode, xDoc);
10761
+ if (converted) {
10762
+ converted.siblingPosition = 0;
10763
+ xDoc.appendChild(converted);
10764
+ }
10765
+ return xDoc;
10766
+ }
10767
+ function convertNode(nativeNode, ownerDoc) {
10768
+ switch (nativeNode.nodeType) {
10769
+ case DOM_ELEMENT_NODE: {
10770
+ const element = nativeNode;
10771
+ const xNode = XNode.create(
10772
+ DOM_ELEMENT_NODE,
10773
+ element.nodeName,
10774
+ null,
10775
+ ownerDoc,
10776
+ element.namespaceURI
10777
+ );
10778
+ xNode.prefix = element.prefix || null;
10779
+ xNode.localName = element.localName || element.nodeName;
10780
+ const attrs = element.attributes;
10781
+ for (let i = 0; i < attrs.length; i++) {
10782
+ const attr = attrs[i];
10783
+ const attrNode = XNode.create(
10784
+ DOM_ATTRIBUTE_NODE,
10785
+ attr.name,
10786
+ attr.value,
10787
+ xNode,
10788
+ attr.namespaceURI
10789
+ );
10790
+ attrNode.prefix = attr.prefix || null;
10791
+ attrNode.localName = attr.localName || attr.name;
10792
+ attrNode.parentNode = xNode;
10793
+ attrNode.siblingPosition = xNode.childNodes.length;
10794
+ xNode.appendChild(attrNode);
10795
+ }
10796
+ const childNodes = nativeNode.childNodes;
10797
+ for (let i = 0; i < childNodes.length; i++) {
10798
+ const converted = convertNode(childNodes[i], ownerDoc);
10799
+ if (converted) {
10800
+ converted.siblingPosition = xNode.childNodes.length;
10801
+ xNode.appendChild(converted);
10802
+ }
10803
+ }
10804
+ return xNode;
10805
+ }
10806
+ case DOM_TEXT_NODE:
10807
+ return XNode.create(DOM_TEXT_NODE, "#text", nativeNode.nodeValue || "", ownerDoc);
10808
+ case DOM_CDATA_SECTION_NODE:
10809
+ return XNode.create(DOM_CDATA_SECTION_NODE, "#cdata-section", nativeNode.nodeValue || "", ownerDoc);
10810
+ case DOM_COMMENT_NODE:
10811
+ return XNode.create(DOM_COMMENT_NODE, "#comment", nativeNode.nodeValue || "", ownerDoc);
10812
+ case DOM_PROCESSING_INSTRUCTION_NODE: {
10813
+ const pi2 = nativeNode;
10814
+ return XNode.create(DOM_PROCESSING_INSTRUCTION_NODE, pi2.target, pi2.data, ownerDoc);
10815
+ }
10816
+ case DOM_DOCUMENT_TYPE_NODE: {
10817
+ const dt = nativeNode;
10818
+ return XNode.create(DOM_DOCUMENT_TYPE_NODE, "#dtd-section", dt.name, ownerDoc);
10819
+ }
10820
+ case DOM_DOCUMENT_FRAGMENT_NODE: {
10821
+ const fragment = XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, "#document-fragment", null, ownerDoc);
10822
+ const childNodes = nativeNode.childNodes;
10823
+ for (let i = 0; i < childNodes.length; i++) {
10824
+ const converted = convertNode(childNodes[i], ownerDoc);
10825
+ if (converted) {
10826
+ converted.siblingPosition = fragment.childNodes.length;
10827
+ fragment.appendChild(converted);
10828
+ }
10829
+ }
10830
+ return fragment;
10831
+ }
10832
+ default:
10833
+ return null;
10834
+ }
10835
+ }
10836
+
10837
+ // src/dom/functions.ts
10838
+ function domGetAttributeValue(node, name) {
10839
+ return node.getAttributeValue(name);
10840
+ }
10841
+ function domSetAttribute(node, name, value) {
10842
+ return node.setAttribute(name, value);
10843
+ }
10844
+ function domAppendChild(node, child) {
10845
+ return node.appendChild(child);
10846
+ }
10847
+ function domCreateTextNode(node, text) {
10848
+ return node.createTextNode(text);
10849
+ }
10850
+ function domCreateElement(doc, name) {
10851
+ return doc.createElement(name);
10852
+ }
10853
+ function domCreateCDATASection(doc, data2) {
10854
+ return doc.createCDATASection(data2);
10855
+ }
10856
+ function domCreateComment(doc, text) {
10857
+ return doc.createComment(text);
10858
+ }
10859
+ function domCreateDocumentFragment(doc) {
10860
+ return doc.createDocumentFragment();
10861
+ }
10862
+ function domCreateDTDSection(doc, data2) {
10863
+ return doc.createDTDSection(data2);
10864
+ }
10865
+ function domCreateProcessingInstruction(doc, target, data2) {
10866
+ return doc.createProcessingInstruction(target, data2);
10867
+ }
10868
+
10772
10869
  // src/dom/html-entity-decoder.ts
10773
10870
  var NAMED_ENTITIES = {
10774
10871
  "amp": "&",
@@ -10973,7 +11070,7 @@ function xmlElementLogicTrivial(node, buffer, options) {
10973
11070
  if (!attribute) {
10974
11071
  continue;
10975
11072
  }
10976
- if (options.outputMethod === "html" && (attribute.nodeName === "xmlns" || attribute.nodeName.startsWith("xmlns:"))) {
11073
+ if (options.outputMethod === "html" && attribute.nodeName === "xmlns" && attribute.nodeValue === "http://www.w3.org/1999/xhtml") {
10977
11074
  continue;
10978
11075
  }
10979
11076
  if (attribute.nodeName && attribute.nodeValue !== null && attribute.nodeValue !== void 0) {
@@ -13908,6 +14005,16 @@ var Xslt = class {
13908
14005
  this.firstTemplateRan = false;
13909
14006
  this.forwardsCompatible = false;
13910
14007
  this.warningsCallback = console.warn.bind(console);
14008
+ this.fetchFunction = options.fetchFunction || ((uri) => __async(this, null, function* () {
14009
+ const globalFetch = typeof globalThis !== "undefined" && typeof globalThis.fetch === "function" ? globalThis.fetch : null;
14010
+ if (!globalFetch) {
14011
+ throw new Error(
14012
+ "No global fetch implementation available. Please provide options.fetchFunction or use a runtime that exposes globalThis.fetch."
14013
+ );
14014
+ }
14015
+ const response = yield globalFetch(uri);
14016
+ return response.text();
14017
+ }));
13911
14018
  this.streamingProcessor = new StreamingProcessor({
13912
14019
  xPath: this.xPath,
13913
14020
  version: ""
@@ -13921,16 +14028,7 @@ var Xslt = class {
13921
14028
  */
13922
14029
  xsltProcess(xmlDoc, stylesheet) {
13923
14030
  return __async(this, null, function* () {
13924
- const outputDocument = new XDocument();
13925
- this.outputDocument = outputDocument;
13926
- const expressionContext = new ExprContext([xmlDoc]);
13927
- expressionContext.warningsCallback = this.warningsCallback;
13928
- if (this.options.parameters.length > 0) {
13929
- for (const parameter of this.options.parameters) {
13930
- expressionContext.setVariable(parameter.name, new StringValue(parameter.value));
13931
- }
13932
- }
13933
- yield this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);
14031
+ const outputDocument = yield this.xsltProcessToDocument(xmlDoc, stylesheet);
13934
14032
  if (this.outputMethod === "json") {
13935
14033
  return xmlToJson(outputDocument);
13936
14034
  }
@@ -13953,6 +14051,32 @@ var Xslt = class {
13953
14051
  return transformedOutputXml;
13954
14052
  });
13955
14053
  }
14054
+ /**
14055
+ * Processes the XSLT transformation and returns the output as an XDocument
14056
+ * instead of a serialized string. This is useful for:
14057
+ * - Working with the result tree programmatically
14058
+ * - Converting to a different DOM representation (e.g., React elements)
14059
+ * - Using browser-native serialization (XMLSerializer) if desired
14060
+ *
14061
+ * @param xmlDoc The input document root, as DOM node.
14062
+ * @param stylesheet The stylesheet document root, as DOM node.
14063
+ * @returns The processed document as an XDocument tree.
14064
+ */
14065
+ xsltProcessToDocument(xmlDoc, stylesheet) {
14066
+ return __async(this, null, function* () {
14067
+ const outputDocument = new XDocument();
14068
+ this.outputDocument = outputDocument;
14069
+ const expressionContext = new ExprContext([xmlDoc]);
14070
+ expressionContext.warningsCallback = this.warningsCallback;
14071
+ if (this.options.parameters.length > 0) {
14072
+ for (const parameter of this.options.parameters) {
14073
+ expressionContext.setVariable(parameter.name, this.toNodeValue(parameter.value));
14074
+ }
14075
+ }
14076
+ yield this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);
14077
+ return outputDocument;
14078
+ });
14079
+ }
13956
14080
  /**
13957
14081
  * The main entry point of the XSL-T processor, as explained on the top of the file.
13958
14082
  * @param context The input document root, as XPath `ExprContext`.
@@ -14572,6 +14696,19 @@ var Xslt = class {
14572
14696
  const value = xmlValueLegacyBehavior(documentFragment);
14573
14697
  if (output) {
14574
14698
  domSetAttribute(output, name, value);
14699
+ if (name.includes(":")) {
14700
+ const prefix = name.split(":")[0];
14701
+ if (prefix !== "xmlns") {
14702
+ const explicitNs = xmlGetAttribute(template, "namespace");
14703
+ const nsUri = explicitNs || this.resolveNamespaceUriForPrefix(template, prefix);
14704
+ if (nsUri) {
14705
+ const nsAttr = `xmlns:${prefix}`;
14706
+ if (!this.isNamespaceDeclaredOnAncestor(output, nsAttr, nsUri)) {
14707
+ domSetAttribute(output, nsAttr, nsUri);
14708
+ }
14709
+ }
14710
+ }
14711
+ }
14575
14712
  }
14576
14713
  });
14577
14714
  }
@@ -14674,6 +14811,12 @@ var Xslt = class {
14674
14811
  domAppendChild(destination, node);
14675
14812
  } else if (source.nodeType == DOM_ATTRIBUTE_NODE) {
14676
14813
  domSetAttribute(destination, source.nodeName, source.nodeValue);
14814
+ if (source.prefix && source.namespaceUri && source.prefix !== "xmlns" && !source.nodeName.startsWith("xmlns")) {
14815
+ const nsAttr = `xmlns:${source.prefix}`;
14816
+ if (!this.isNamespaceDeclaredOnAncestor(destination, nsAttr, source.namespaceUri)) {
14817
+ domSetAttribute(destination, nsAttr, source.namespaceUri);
14818
+ }
14819
+ }
14677
14820
  }
14678
14821
  return null;
14679
14822
  }
@@ -15341,16 +15484,6 @@ var Xslt = class {
15341
15484
  xsltImportOrInclude(context, template, output, isImport) {
15342
15485
  return __async(this, null, function* () {
15343
15486
  const elementName = isImport ? "xsl:import" : "xsl:include";
15344
- const [major, minor] = process.versions.node.split(".").map(Number);
15345
- if (major <= 17 && minor < 5) {
15346
- throw new Error(`Your Node.js version does not support \`<${elementName}>\`. If possible, please update your Node.js version to at least version 17.5.0.`);
15347
- }
15348
- if (!global.globalThis.fetch) {
15349
- global.globalThis.fetch = fetch;
15350
- global.globalThis.Headers = Headers;
15351
- global.globalThis.Request = Request;
15352
- global.globalThis.Response = Response;
15353
- }
15354
15487
  const hrefAttributeFind = template.childNodes.filter((n) => n.nodeName === "href");
15355
15488
  if (hrefAttributeFind.length <= 0) {
15356
15489
  throw new Error(`<${elementName}> with no href attribute defined.`);
@@ -15360,8 +15493,7 @@ var Xslt = class {
15360
15493
  if (this.importedStylesheets.has(href)) {
15361
15494
  return;
15362
15495
  }
15363
- const fetchTest = yield global.globalThis.fetch(href);
15364
- const fetchResponse = yield fetchTest.text();
15496
+ const fetchResponse = yield this.fetchFunction(href);
15365
15497
  const includedXslt = this.xmlParser.xmlParse(fetchResponse);
15366
15498
  const currentDepth = this.styleSheetStack.length > 0 ? this.styleSheetStack[this.styleSheetStack.length - 1].importDepth : 0;
15367
15499
  const metadata = {
@@ -17171,6 +17303,29 @@ var Xslt = class {
17171
17303
  return value;
17172
17304
  }
17173
17305
  }
17306
+ /**
17307
+ * Converts a raw JavaScript value to the appropriate NodeValue type.
17308
+ * Detects NodeValue instances, DOM nodes, arrays, numbers, booleans,
17309
+ * and falls back to StringValue.
17310
+ *
17311
+ * @param value The raw value to convert.
17312
+ * @returns The wrapped NodeValue.
17313
+ */
17314
+ toNodeValue(value) {
17315
+ if (value && typeof value === "object" && "stringValue" in value) {
17316
+ return value;
17317
+ } else if (value && typeof value === "object" && "nodeType" in value) {
17318
+ return new NodeSetValue([value]);
17319
+ } else if (Array.isArray(value)) {
17320
+ return new NodeSetValue(value);
17321
+ } else if (typeof value === "number") {
17322
+ return new NumberValue(value);
17323
+ } else if (typeof value === "boolean") {
17324
+ return new BooleanValue(value);
17325
+ } else {
17326
+ return new StringValue(String(value != null ? value : ""));
17327
+ }
17328
+ }
17174
17329
  /**
17175
17330
  * Execute a user-defined xsl:function.
17176
17331
  * Called when a function from userDefinedFunctions is invoked from XPath.
@@ -17208,30 +17363,10 @@ var Xslt = class {
17208
17363
  const paramName = xmlGetAttribute(params[i], "name");
17209
17364
  if (paramName) {
17210
17365
  if (i < args.length) {
17211
- let argValue = args[i];
17212
17366
  const paramType = xmlGetAttribute(params[i], "as");
17213
- let paramValue;
17214
- if (argValue && typeof argValue === "object" && "stringValue" in argValue) {
17215
- paramValue = argValue;
17216
- if (paramType) {
17217
- paramValue = this.coerceToType(paramValue, paramType);
17218
- }
17219
- } else if (argValue && typeof argValue === "object" && "nodeType" in argValue) {
17220
- paramValue = new NodeSetValue([argValue]);
17221
- if (paramType) {
17222
- paramValue = this.coerceToType(paramValue, paramType);
17223
- }
17224
- } else if (Array.isArray(argValue)) {
17225
- paramValue = new NodeSetValue(argValue);
17226
- if (paramType) {
17227
- paramValue = this.coerceToType(paramValue, paramType);
17228
- }
17229
- } else if (typeof argValue === "number") {
17230
- paramValue = new NumberValue(argValue);
17231
- } else if (typeof argValue === "boolean") {
17232
- paramValue = new BooleanValue(argValue);
17233
- } else {
17234
- paramValue = new StringValue(String(argValue != null ? argValue : ""));
17367
+ let paramValue = this.toNodeValue(args[i]);
17368
+ if (paramType) {
17369
+ paramValue = this.coerceToType(paramValue, paramType);
17235
17370
  }
17236
17371
  functionContext.setVariable(paramName, paramValue);
17237
17372
  } else {
@@ -17438,12 +17573,12 @@ var Xslt = class {
17438
17573
  } else if (select) {
17439
17574
  value = this.xPath.xPathEval(select, context);
17440
17575
  } else {
17441
- let parameterValue = "";
17442
17576
  const filteredParameter = this.options.parameters.filter((p) => p.name === name);
17443
17577
  if (filteredParameter.length > 0) {
17444
- parameterValue = filteredParameter[0].value;
17578
+ value = this.toNodeValue(filteredParameter[0].value);
17579
+ } else {
17580
+ value = new StringValue("");
17445
17581
  }
17446
- value = new StringValue(parameterValue);
17447
17582
  }
17448
17583
  if (override || !context.getVariable(name)) {
17449
17584
  context.setVariable(name, value);
@@ -17608,6 +17743,12 @@ var Xslt = class {
17608
17743
  const name = attribute.nodeName;
17609
17744
  const value = this.xsltAttributeValue(attribute.nodeValue, elementContext);
17610
17745
  domSetAttribute(newNode, name, value);
17746
+ if (attribute.prefix && attribute.namespaceUri && attribute.prefix !== "xmlns" && !attribute.nodeName.startsWith("xmlns")) {
17747
+ const nsAttr = `xmlns:${attribute.prefix}`;
17748
+ if (!this.isNamespaceDeclaredOnAncestor(newNode, nsAttr, attribute.namespaceUri)) {
17749
+ domSetAttribute(newNode, nsAttr, attribute.namespaceUri);
17750
+ }
17751
+ }
17611
17752
  }
17612
17753
  break;
17613
17754
  default:
@@ -18012,9 +18153,12 @@ var Xslt = class {
18012
18153
  // Annotate the CommonJS export names for ESM import in node:
18013
18154
  0 && (module.exports = {
18014
18155
  ExprContext,
18156
+ XDocument,
18157
+ XNode,
18015
18158
  XPath,
18016
18159
  XmlParser,
18017
18160
  Xslt,
18161
+ domDocumentToXDocument,
18018
18162
  xmlEscapeText
18019
18163
  });
18020
18164
  //# sourceMappingURL=index.js.map