0.13.1 • Published 2 years ago

@xmpp/xml v0.13.1

Weekly downloads
15,044
License
ISC
Repository
github
Last release
2 years ago

xml

Install

Note, if you're using @xmpp/client or @xmpp/component, you don't need to install @xmpp/xml.

npm install @xmpp/xml

const xml = require("@xmpp/xml");
const { xml } = require("@xmpp/client");
const { xml } = require("@xmpp/component");

Writing

There's 2 methods for writing XML with xmpp.js

factory

const xml = require("@xmpp/xml");

const recipient = "user@example.com";
const days = ["Monday", "Tuesday", "Wednesday"];
const message = xml(
  "message",
  { to: recipient },
  xml("body", {}, 1 + 2),
  xml(
    "days",
    {},
    days.map((day, idx) => xml("day", { idx }, day)),
  ),
);

If the second argument passed to xml is a string instead of an object, it will be set as the xmlns attribute.

// both are equivalent
xml("time", "urn:xmpp:time");
xml("time", { xmlns: "urn:xmpp:time" });

JSX

/** @jsx xml */

const xml = require("@xmpp/xml");

const recipient = "user@example.com";
const days = ["Monday", "Tuesday"];
const message = (
  <message to={recipient}>
    <body>{1 + 2}</body>
    <days>
      {days.map((day, idx) => (
        <day idx={idx}>${day}</day>
      ))}
    </days>
  </message>
);

Requires a preprocessor such as TypeScript or Babel with @babel/plugin-transform-react-jsx.

Reading

attributes

The attrs property is an object that holds xml attributes of the element.

message.attrs.to; // user@example.com

text

Returns the text value of an element

message.getChild("body").text(); // '3'

getChild

Get child element by name.

message.getChild("body").toString(); // '<body>3</body>'

getChildText

Get child element text value.

message.getChildText("body"); // '3'

getChildren

Get children elements by name.

message.getChild("days").getChildren("day"); // [...]

Since getChildren returns an array, you can use JavaScript array methods such as filter and find to build more complex queries.

const days = message.getChild("days").getChildren("day");

// Find Monday element
days.find((day) => day.text() === "Monday");
days.find((day) => day.attrs.idx === 0);

// Find all days after Tuesday
days.filter((day) => day.attrs.idx > 2);

parent

You can get the parent node using the parent property.

console.log(message.getChild("days").parent === message);

root

You can get the root node using the root method.

console.log(message.getChild("days").root() === message);

Editing

attributes

The attrs property is an object that holds xml attributes of the element.

message.attrs.type = "chat";
Object.assign(message.attrs, { type: "chat" });

text

Set the text value of an element

message.getChild("body").text("Hello world");

append

Adds text or element nodes to the last position. Returns the parent.

message.append(xml("foo"));
message.append("bar");
message.append(days.map((day) => xml("day", {}, day)));
// <message>
//   ...
//   <foo/>
//   bar
//   <day>Monday</day>
//   <day>Tuesday</day>
// </message>

prepend

Adds text or element nodes to the first position. Returns the parent.

message.prepend(xml("foo"));
message.prepend("bar");
message.prepend(days.map((day) => xml("day", {}, day)));
// <message>
//   <day>Tuesday</day>
//   <day>Monday</day>
//   bar
//   <foo/>
//   ...
// </message>

remove

Removes a child element.

const body = message.getChild("body");
message.remove(body);

JSON

You can embed JSON anywhere but it is recommended to use appropriate semantic.

/** @jsx xml */

// write
message.append(
  <myevent xmlns="xmpp:example.org">
    <json xmlns="urn:xmpp:json:0">{JSON.stringify(days)}</json>
  </myevent>,
);

// read
JSON.parse(
  message
    .getChild("myevent", "xmpp:example.org")
    .getChildText("json", "urn:xmpp:json:0"),
);

See also JSON Containers and Simple JSON Messaging.

Parsing XML strings

@xmpp/xml include a function to parse XML strings.

⚠ Use with care. Untrusted input or substitutions can result in invalid XML and side effects.

const { escapeXML, escapeXMLText };
const parse = require("@xmpp/xml/lib/parse");

const ctx = parse("<message><body>hello world</body></message>");
ctx.getChildText("body"); // hello world

If you must use with untrusted input, escape it with escapeXML and escapeXMLText.

const { escapeXML, escapeXMLText } = require("@xmpp/xml");
const parse = require("@xmpp/xml/lib/parse");

const message = parse(`
  <message to="${escapeXML(to)}">
    <body>${escapeXMLText(body)}</body>
  </message>,
`);