mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-11-13 12:13:42 +01:00
fix(template-function-xml): return attribute and text() values from XPath (#723)
This commit is contained in:
1 parent
7f30253616
commit
d44d75dcef
3 files changed
+48
-3
No files matched your search
@@ -8,7 +8,8 @@
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "yaakcli build",
|
||||
"dev": "yaakcli dev"
|
||||
"dev": "yaakcli dev",
|
||||
"test": "vp test --run tests"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.9.12",
|
||||
|
||||
@@ -77,11 +77,19 @@ export function filterXPath(
|
||||
return String(items);
|
||||
}
|
||||
if (!Array.isArray(items) || result === "first") {
|
||||
return items[0] != null ? String(items[0].firstChild ?? "") : "";
|
||||
return items[0] != null ? nodeText(items[0]) : "";
|
||||
}
|
||||
if (result === "join") {
|
||||
return items.map((item) => String(item.firstChild ?? "")).join(join ?? "");
|
||||
return items.map(nodeText).join(join ?? "");
|
||||
}
|
||||
// Not sure what cases this happens in (?)
|
||||
return String(items);
|
||||
}
|
||||
|
||||
function nodeText(node: Node): string {
|
||||
// Attribute, text and CDATA nodes have no children, so their value is on the node itself
|
||||
if (xpath.isAttribute(node) || xpath.isTextNode(node) || xpath.isCDATASection(node)) {
|
||||
return node.nodeValue ?? "";
|
||||
}
|
||||
return String(node.firstChild ?? "");
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Context } from "@yaakapp/api";
|
||||
import { describe, expect, it } from "vite-plus/test";
|
||||
import { filterXPath, plugin } from "../src";
|
||||
|
||||
const USERS =
|
||||
'<users><user id="42"><name>Alice</name></user><user id="7"><name>Bob</name></user></users>';
|
||||
|
||||
describe("xml.xpath", () => {
|
||||
const xpathFunction = plugin.templateFunctions?.find((f) => f.name === "xml.xpath");
|
||||
|
||||
const select = async (query: string, result = "first", join = ", ") =>
|
||||
await xpathFunction?.onRender({} as Context, {
|
||||
values: { input: USERS, query, result, join },
|
||||
purpose: "send",
|
||||
});
|
||||
|
||||
it("returns the text of a selected element", async () => {
|
||||
expect(await select("//user/name")).toBe("Alice");
|
||||
});
|
||||
|
||||
it("returns the value of a selected attribute", async () => {
|
||||
expect(await select("//user/@id")).toBe("42");
|
||||
});
|
||||
|
||||
it("joins the values of selected attributes", async () => {
|
||||
expect(await select("//user/@id", "join")).toBe("42, 7");
|
||||
});
|
||||
|
||||
it("returns the value of a selected text node", async () => {
|
||||
expect(await select("//user/name/text()")).toBe("Alice");
|
||||
});
|
||||
|
||||
it("returns the value of a selected CDATA section", () => {
|
||||
expect(filterXPath("<a><![CDATA[x<y]]></a>", "/a/text()", "first", null)).toBe("x<y");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user