pull:初次提交
This commit is contained in:
24
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/Xml.node.json
Executable file
24
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/Xml.node.json
Executable file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"node": "n8n-nodes-base.xml",
|
||||
"nodeVersion": "1.0",
|
||||
"codexVersion": "1.0",
|
||||
"categories": ["Core Nodes"],
|
||||
"resources": {
|
||||
"primaryDocumentation": [
|
||||
{
|
||||
"url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.xml/"
|
||||
}
|
||||
],
|
||||
"generic": [
|
||||
{
|
||||
"label": "What are APIs and how to use them with no code",
|
||||
"icon": " 🪢",
|
||||
"url": "https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"alias": ["Parse"],
|
||||
"subcategories": {
|
||||
"Core Nodes": ["Data Transformation"]
|
||||
}
|
||||
}
|
||||
300
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/Xml.node.ts
Executable file
300
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/Xml.node.ts
Executable file
@@ -0,0 +1,300 @@
|
||||
import type {
|
||||
IExecuteFunctions,
|
||||
INodeExecutionData,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeConnectionTypes, NodeOperationError, deepCopy } from 'n8n-workflow';
|
||||
import { Builder, Parser } from 'xml2js';
|
||||
|
||||
export class Xml implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'XML',
|
||||
name: 'xml',
|
||||
icon: 'fa:file-code',
|
||||
iconColor: 'purple',
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["mode"]==="jsonToxml" ? "JSON to XML" : "XML to JSON"}}',
|
||||
description: 'Convert data from and to XML',
|
||||
defaults: {
|
||||
name: 'XML',
|
||||
color: '#333377',
|
||||
},
|
||||
inputs: [NodeConnectionTypes.Main],
|
||||
outputs: [NodeConnectionTypes.Main],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Mode',
|
||||
name: 'mode',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'JSON to XML',
|
||||
value: 'jsonToxml',
|
||||
description: 'Converts data from JSON to XML',
|
||||
},
|
||||
{
|
||||
name: 'XML to JSON',
|
||||
value: 'xmlToJson',
|
||||
description: 'Converts data from XML to JSON',
|
||||
},
|
||||
],
|
||||
default: 'xmlToJson',
|
||||
description: 'From and to what format the data should be converted',
|
||||
},
|
||||
{
|
||||
displayName:
|
||||
"If your XML is inside a binary file, use the 'Extract from File' node to convert it to text first",
|
||||
name: 'xmlNotice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
mode: ['xmlToJson'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// option:jsonToxml
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Property Name',
|
||||
name: 'dataPropertyName',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
mode: ['jsonToxml'],
|
||||
},
|
||||
},
|
||||
default: 'data',
|
||||
required: true,
|
||||
description: 'Name of the property to which to contains the converted XML data',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add option',
|
||||
displayOptions: {
|
||||
show: {
|
||||
mode: ['jsonToxml'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Allow Surrogate Chars',
|
||||
name: 'allowSurrogateChars',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to allow using characters from the Unicode surrogate blocks',
|
||||
},
|
||||
{
|
||||
displayName: 'Attribute Key',
|
||||
name: 'attrkey',
|
||||
type: 'string',
|
||||
default: '$',
|
||||
description: 'Prefix that is used to access the attributes',
|
||||
},
|
||||
{
|
||||
displayName: 'Cdata',
|
||||
name: 'cdata',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether to wrap text nodes in <![CDATA[ ... ]]> instead of escaping when necessary. Does not add <![CDATA[ ... ]]> if it is not required.',
|
||||
},
|
||||
{
|
||||
displayName: 'Character Key',
|
||||
name: 'charkey',
|
||||
type: 'string',
|
||||
default: '_',
|
||||
description: 'Prefix that is used to access the character content',
|
||||
},
|
||||
{
|
||||
displayName: 'Headless',
|
||||
name: 'headless',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to omit the XML header',
|
||||
},
|
||||
{
|
||||
displayName: 'Root Name',
|
||||
name: 'rootName',
|
||||
type: 'string',
|
||||
default: 'root',
|
||||
description: 'Root element name to be used',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// option:xmlToJson
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Property Name',
|
||||
name: 'dataPropertyName',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
mode: ['xmlToJson'],
|
||||
},
|
||||
},
|
||||
default: 'data',
|
||||
required: true,
|
||||
description: 'Name of the property which contains the XML data to convert',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add option',
|
||||
displayOptions: {
|
||||
show: {
|
||||
mode: ['xmlToJson'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Attribute Key',
|
||||
name: 'attrkey',
|
||||
type: 'string',
|
||||
default: '$',
|
||||
description: 'Prefix that is used to access the attributes',
|
||||
},
|
||||
{
|
||||
displayName: 'Character Key',
|
||||
name: 'charkey',
|
||||
type: 'string',
|
||||
default: '_',
|
||||
description: 'Prefix that is used to access the character content',
|
||||
},
|
||||
{
|
||||
displayName: 'Explicit Array',
|
||||
name: 'explicitArray',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether to always put child nodes in an array if true; otherwise an array is created only if there is more than one',
|
||||
},
|
||||
{
|
||||
displayName: 'Explicit Root',
|
||||
name: 'explicitRoot',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description:
|
||||
'Whether to set this if you want to get the root node in the resulting object',
|
||||
},
|
||||
{
|
||||
displayName: 'Ignore Attributes',
|
||||
name: 'ignoreAttrs',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to ignore all XML attributes and only create text nodes',
|
||||
},
|
||||
{
|
||||
displayName: 'Merge Attributes',
|
||||
name: 'mergeAttrs',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description:
|
||||
'Whether to merge attributes and child elements as properties of the parent, instead of keying attributes off a child attribute object. This option is ignored if ignoreAttrs is true.',
|
||||
},
|
||||
{
|
||||
displayName: 'Normalize',
|
||||
name: 'normalize',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to trim whitespaces inside text nodes',
|
||||
},
|
||||
{
|
||||
displayName: 'Normalize Tags',
|
||||
name: 'normalizeTags',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to normalize all tag names to lowercase',
|
||||
},
|
||||
{
|
||||
displayName: 'Trim',
|
||||
name: 'trim',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to trim the whitespace at the beginning and end of text nodes',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = this.getInputData();
|
||||
|
||||
const mode = this.getNodeParameter('mode', 0) as string;
|
||||
const dataPropertyName = this.getNodeParameter('dataPropertyName', 0);
|
||||
const options = this.getNodeParameter('options', 0, {});
|
||||
|
||||
let item: INodeExecutionData;
|
||||
const returnData: INodeExecutionData[] = [];
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
try {
|
||||
item = items[itemIndex];
|
||||
|
||||
if (mode === 'xmlToJson') {
|
||||
const parserOptions = Object.assign(
|
||||
{
|
||||
mergeAttrs: true,
|
||||
explicitArray: false,
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
const parser = new Parser(parserOptions);
|
||||
|
||||
if (item.json[dataPropertyName] === undefined) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
`Item has no JSON property called "${dataPropertyName}"`,
|
||||
{ itemIndex },
|
||||
);
|
||||
}
|
||||
|
||||
const json = await parser.parseStringPromise(item.json[dataPropertyName] as string);
|
||||
returnData.push({ json: deepCopy(json) });
|
||||
} else if (mode === 'jsonToxml') {
|
||||
const builder = new Builder(options);
|
||||
|
||||
returnData.push({
|
||||
json: {
|
||||
[dataPropertyName]: builder.buildObject(items[itemIndex].json),
|
||||
},
|
||||
pairedItem: {
|
||||
item: itemIndex,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
throw new NodeOperationError(this.getNode(), `The operation "${mode}" is not known!`, {
|
||||
itemIndex,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
items[itemIndex] = {
|
||||
json: {
|
||||
error: error.message,
|
||||
},
|
||||
pairedItem: {
|
||||
item: itemIndex,
|
||||
},
|
||||
};
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [returnData];
|
||||
}
|
||||
}
|
||||
5
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/test/node/Xml.test.ts
Executable file
5
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/test/node/Xml.test.ts
Executable file
@@ -0,0 +1,5 @@
|
||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
|
||||
describe('Test XML Node', () => {
|
||||
new NodeTestHarness().setupTests();
|
||||
});
|
||||
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"name": "My workflow",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "7f04c09e-5a60-4a0c-a336-ef38e4732452",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [860, 380]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return [\n {\n json: {\n a: {\n b: {\n c: 1\n }\n }\n }\n }\n];\n"
|
||||
},
|
||||
"id": "be80ce82-d312-460d-ac79-05c0626845ad",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [1080, 380]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "jsonToxml",
|
||||
"options": {}
|
||||
},
|
||||
"id": "c352655b-e0dc-4f7c-a63a-ff1bc5f1909f",
|
||||
"name": "XML",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [1300, 380]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "21547e44-133e-4c3b-a601-0cffba1daf9b",
|
||||
"name": "XML1",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [1500, 380]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"values": {
|
||||
"string": [
|
||||
{
|
||||
"name": "new",
|
||||
"value": "={{ $json.a }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {}
|
||||
},
|
||||
"id": "632dee22-10d1-424d-b1d2-673b95b32943",
|
||||
"name": "Set",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"typeVersion": 2,
|
||||
"position": [1720, 380]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"Set": [
|
||||
{
|
||||
"json": {
|
||||
"a": {
|
||||
"b": {
|
||||
"c": "1"
|
||||
}
|
||||
},
|
||||
"new": {
|
||||
"b": {
|
||||
"c": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "XML",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"XML": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "XML1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"XML1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Set",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "14c1d4b8-3546-4692-8e8a-44c244c79bcc",
|
||||
"id": "0G78Fh2FTnM46kuR",
|
||||
"meta": {
|
||||
"instanceId": "021d3c82ba2d3bc090cbf4fc81c9312668bcc34297e022bb3438c5c88a43a5ff"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
148
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/test/node/workflow.xml.json
Executable file
148
n8n-n8n-1.109.2/packages/nodes-base/nodes/Xml/test/node/workflow.xml.json
Executable file
@@ -0,0 +1,148 @@
|
||||
{
|
||||
"name": "xml tests",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "745d1191-f221-4eda-9d09-611233f97edd",
|
||||
"name": "When clicking \"Execute Workflow\"",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [460, 520]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "jsonToxml",
|
||||
"options": {}
|
||||
},
|
||||
"id": "fb48ca4c-5ae2-4c57-9ca9-2080d06dbf65",
|
||||
"name": "XML",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [960, 280]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n data: {\n id: 1,\n firstName: 'Adam',\n secondName: 'Smith',\n fullName: 'Adam Smith',\n }\n}"
|
||||
},
|
||||
"id": "6a04ca32-c9cc-4cb1-a6b9-3a505b1c2dd5",
|
||||
"name": "Code",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [700, 400]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"mode": "jsonToxml",
|
||||
"options": {
|
||||
"headless": true
|
||||
}
|
||||
},
|
||||
"id": "cd740e65-5117-4bec-a3b3-6863ba25f232",
|
||||
"name": "XML1",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [960, 500]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "return {\n\"data\":\n'<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <data> <id>1</id> <firstName>Adam</firstName> <secondName>Smith</secondName> <fullName>Adam Smith</fullName> </data>'\n}"
|
||||
},
|
||||
"id": "817afbf7-9342-403f-8dc0-c4a3905fde4d",
|
||||
"name": "Code1",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 1,
|
||||
"position": [680, 640]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"options": {}
|
||||
},
|
||||
"id": "f0f37a8f-9136-42e8-be34-f32b77e4aa88",
|
||||
"name": "XML2",
|
||||
"type": "n8n-nodes-base.xml",
|
||||
"typeVersion": 1,
|
||||
"position": [940, 700]
|
||||
}
|
||||
],
|
||||
"pinData": {
|
||||
"XML": [
|
||||
{
|
||||
"json": {
|
||||
"data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<data>\n <id>1</id>\n <firstName>Adam</firstName>\n <secondName>Smith</secondName>\n <fullName>Adam Smith</fullName>\n</data>"
|
||||
}
|
||||
}
|
||||
],
|
||||
"XML1": [
|
||||
{
|
||||
"json": {
|
||||
"data": "<data>\n <id>1</id>\n <firstName>Adam</firstName>\n <secondName>Smith</secondName>\n <fullName>Adam Smith</fullName>\n</data>"
|
||||
}
|
||||
}
|
||||
],
|
||||
"XML2": [
|
||||
{
|
||||
"json": {
|
||||
"data": {
|
||||
"id": "1",
|
||||
"firstName": "Adam",
|
||||
"secondName": "Smith",
|
||||
"fullName": "Adam Smith"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"connections": {
|
||||
"When clicking \"Execute Workflow\"": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Code",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "Code1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "XML",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"node": "XML1",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Code1": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "XML2",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {},
|
||||
"versionId": "c1fde9d5-f27c-4e62-bc5c-8be787dcc227",
|
||||
"id": "109",
|
||||
"meta": {
|
||||
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user