xslt-processor 4.8.2 → 4.8.4

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 CHANGED
@@ -80,7 +80,7 @@ const xslt = new Xslt(options);
80
80
  - `cData` (`boolean`, default `true`): resolves CDATA elements in the output. Content under CDATA is resolved as text. This overrides `escape` for CDATA content.
81
81
  - `escape` (`boolean`, default `true`): replaces symbols like `<`, `>`, `&` and `"` by the corresponding [HTML/XML entities](https://www.tutorialspoint.com/xml/xml_character_entities.htm). Can be overridden by `disable-output-escaping`, that also does the opposite, unescaping `&gt;` and `&lt;` by `<` and `>`, respectively.
82
82
  - `selfClosingTags` (`boolean`, default `true`): Self-closes tags that don't have inner elements, if `true`. For instance, `<test></test>` becomes `<test />`.
83
- - `outputMethod` (`string`, default `xml`): Specifies the default output method. if `<xsl:output>` is declared in your XSLT file, this will be overridden. Valid values: `xml`, `html`, `text`, `name`, `xhtml`, `json`.
83
+ - `outputMethod` (`string`, default `xml`): Specifies the default output method. if `<xsl:output>` is declared in your XSLT file, this will be overridden. Valid values: `xml`, `html`, `text`, `name`, `xhtml`, `json`, `adaptive`.
84
84
  - `parameters` (`array`, default `[]`): external parameters that you want to use.
85
85
  - `name`: the parameter name;
86
86
  - `namespaceUri` (optional): the namespace;
@@ -131,6 +131,52 @@ console.log(parsed.root.users.user); // ["Alice", "Bob"]
131
131
  - Attributes are prefixed with `@` (when present in the output)
132
132
  - Mixed text and element content uses the `#text` property for text nodes
133
133
 
134
+ #### Adaptive Output Format
135
+
136
+ When using `outputMethod: 'adaptive'`, the XSLT processor automatically detects the most appropriate output format based on the transformation result. This implements XSLT 3.1 adaptive output behavior.
137
+
138
+ **Detection Rules:**
139
+
140
+ - If the output contains only text nodes (no elements), it returns as plain text
141
+ - If the output contains one or more elements, it returns as XML
142
+
143
+ **Example:**
144
+
145
+ ```js
146
+ const xslt = new Xslt({ outputMethod: 'adaptive' });
147
+ const xmlParser = new XmlParser();
148
+
149
+ // Example 1: Pure text output
150
+ const xmlString1 = `<root><value>Hello World</value></root>`;
151
+ const xsltString1 = `<?xml version="1.0"?>
152
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
153
+ <xsl:template match="/">
154
+ <xsl:value-of select="root/value"/>
155
+ </xsl:template>
156
+ </xsl:stylesheet>`;
157
+
158
+ const result1 = await xslt.xsltProcess(
159
+ xmlParser.xmlParse(xmlString1),
160
+ xmlParser.xmlParse(xsltString1)
161
+ );
162
+ console.log(result1); // "Hello World" (plain text)
163
+
164
+ // Example 2: XML output
165
+ const xmlString2 = `<root><user>John</user></root>`;
166
+ const xsltString2 = `<?xml version="1.0"?>
167
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
168
+ <xsl:template match="/">
169
+ <users><xsl:copy-of select="root/user"/></users>
170
+ </xsl:template>
171
+ </xsl:stylesheet>`;
172
+
173
+ const result2 = await xslt.xsltProcess(
174
+ xmlParser.xmlParse(xmlString2),
175
+ xmlParser.xmlParse(xsltString2)
176
+ );
177
+ console.log(result2); // "<users><user>John</user></users>" (XML)
178
+ ```
179
+
134
180
  ### Direct use in browsers
135
181
 
136
182
  You can simply add a tag like this:
package/index.js CHANGED
@@ -9028,9 +9028,13 @@ var XPathBaseParser = class {
9028
9028
  return expr;
9029
9029
  }
9030
9030
  parsePrimaryExpr() {
9031
- var _a, _b;
9031
+ var _a, _b, _c;
9032
9032
  if (this.match("DOLLAR")) {
9033
- const name = this.consume("IDENTIFIER", "Expected variable name after $").lexeme;
9033
+ const next = this.peek();
9034
+ if (!next || !this.isNcNameToken(next.type)) {
9035
+ throw grammarViolation(`Expected variable name after $. Got: ${(_a = next == null ? void 0 : next.lexeme) != null ? _a : "EOF"}`);
9036
+ }
9037
+ const name = this.advance().lexeme;
9034
9038
  return new XPathVariableReference(name);
9035
9039
  }
9036
9040
  if (this.match("OPEN_PAREN")) {
@@ -9054,7 +9058,7 @@ var XPathBaseParser = class {
9054
9058
  return this.parseFunctionCall();
9055
9059
  }
9056
9060
  throw grammarViolation(
9057
- `Unexpected token in primary expression: ${(_b = (_a = this.peek()) == null ? void 0 : _a.lexeme) != null ? _b : "EOF"}`
9061
+ `Unexpected token in primary expression: ${(_c = (_b = this.peek()) == null ? void 0 : _b.lexeme) != null ? _c : "EOF"}`
9058
9062
  );
9059
9063
  }
9060
9064
  parseFunctionCall() {
@@ -14747,8 +14751,9 @@ var Xslt = class {
14747
14751
  if (useAttributeSets) {
14748
14752
  yield this.applyAttributeSets(context, node, useAttributeSets);
14749
14753
  }
14754
+ node.siblingPosition = (output || this.outputDocument).childNodes.length;
14750
14755
  domAppendChild(output || this.outputDocument, node);
14751
- const clonedContext = context.clone(void 0, 0);
14756
+ const clonedContext = context.clone();
14752
14757
  yield this.xsltChildNodes(clonedContext, template, node);
14753
14758
  });
14754
14759
  }