📅  最后修改于: 2023-12-03 15:38:58.355000             🧑  作者: Mango
在 C# 代码中操作 XML 文档是非常常见的需求。当我们想要在 TypeScript 代码中执行类似的任务时,需要使用一些额外的工具和技巧。
本文将介绍如何在 TypeScript 中操作 XML 文档,具体内容如下:
使用 TypeScript 操作 XML 文档需要安装一些依赖。在此之前,确保已安装 Node.js 和 TypeScript。
安装依赖:
npm install --save xmldom xpath
npm install --save-dev @types/xmldom @types/xpath
xmldom
:一个纯 JavaScript 实现的 DOM 解析器,可以解析 XML 文档并提供 DOM API。xpath
:一个用于在 XML 文档中选取节点的库。@types/xmldom
和 @types/xpath
:类型定义文件,TypeScript 中使用这些库时需要。假设我们有一个名为 books.xml
的 XML 文档:
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<!-- ... more books ... -->
</catalog>
我们可以使用 xmldom
库加载这个 XML 文档:
import { DOMParser } from 'xmldom';
const xmlString = `<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<!-- ... more books ... -->
</catalog>`;
const xmlDom = new DOMParser().parseFromString(xmlString, 'text/xml');
DOMParser
:将 XML 字符串解析为 DOM 对象。现在我们已经成功加载了 XML 文档,可以开始操作。
假设我们想要修改 books.xml
中所有 book
的 price
元素,将其加上 10,只保留小数点后两位。
可以使用 xpath
库选取所有 book
元素,然后遍历这些元素,进行修改。
import { XPathEvaluator } from 'xpath';
const xpath = new XPathEvaluator();
const books = xpath.evaluate('/catalog/book', xmlDom, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < books.snapshotLength; i++) {
const book = books.snapshotItem(i);
const price = book.getElementsByTagName('price')[0];
const originalPrice = +price.textContent;
if (!isNaN(originalPrice)) {
const newPrice = (originalPrice + 10).toFixed(2);
price.textContent = newPrice;
}
}
XPathEvaluator
:根据 XPath 表达式选取 XML 元素。XPathEvaluator.evaluate
方法可以选取所有符合给定 XPath 表达式的 XML 元素。接下来,我们遍历这些元素,对每个元素的 price
元素的值进行修改。
需要注意的是,textContent
属性返回的是字符串类型,需要使用 +
运算符将其转换为数字类型,以便进行加法运算。
现在,我们已经完成了对 XML 文档的修改。如果想要将这些修改保存到原始 XML 文件中,可以使用 xmlserializer
库将 DOM 对象转换为字符串,然后将字符串写入文件。
import { XMLSerializer } from 'xmldom';
import { writeFile } from 'fs/promises';
const serializer = new XMLSerializer();
const newXmlString = serializer.serializeToString(xmlDom);
await writeFile('books.xml', newXmlString);
XMLSerializer
:将 DOM 对象序列化为 XML 字符串。下面是完整的代码示例,可供参考:
import { DOMParser } from 'xmldom';
import { XPathEvaluator } from 'xpath';
import { XMLSerializer } from 'xmldom';
import { writeFile } from 'fs/promises';
async function updateXmlDocument() {
const xmlString = `<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<!-- ... more books ... -->
</catalog>`;
const xmlDom = new DOMParser().parseFromString(xmlString, 'text/xml');
const xpath = new XPathEvaluator();
const books = xpath.evaluate('/catalog/book', xmlDom, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < books.snapshotLength; i++) {
const book = books.snapshotItem(i);
const price = book.getElementsByTagName('price')[0];
const originalPrice = +price.textContent;
if (!isNaN(originalPrice)) {
const newPrice = (originalPrice + 10).toFixed(2);
price.textContent = newPrice;
}
}
const serializer = new XMLSerializer();
const newXmlString = serializer.serializeToString(xmlDom);
await writeFile('books.xml', newXmlString);
}
updateXmlDocument();