前言

在移动开发中,XML(Extensible Markup Language)虽然不如 JSON 流行,但在企业级场景中仍然大量存在——SOAP 接口、RSS 订阅、配置文件、办公文档(如 OOXML 格式的 .docx/.xlsx),底层都是 XML。处理这些数据时,你当然可以手写正则或字符串解析,但那意味着你要自己处理嵌套标签、属性、注释、CDATA、实体转义等繁琐细节。

HarmonyOS NEXT 提供了 @ohos.convertxml 模块,一行 API 就能把 XML 字符串变成结构化的 JavaScript 对象,并且通过 ConvertOptions 精细控制解析行为:是否保留属性、是否忽略注释、自定义输出键名等等。

本文用一个可交互的"XML 解析实验室",把 @ohos.convertxml 讲透:切换 5 种解析选项、加载 4 种不同场景的 XML 样本、实时查看解析结果。全文含完整可运行代码,适合需要在鸿蒙应用中处理 XML 数据的中级开发者。


一、@ohos.convertxml 概述

1.1 模块定位

@ohos.convertxml 是 HarmonyOS 提供的 XML 解析工具,位于 @kit.ArkTS 工具库中。核心功能一言蔽之:将 XML 字符串转换为 JavaScript 对象。转换后的对象可以直接用 JSON.stringify 序列化,也可以通过点号访问属性,极大简化了 XML 数据的读取流程。

1.2 核心 API:ConvertXML 类

从 API 14 开始,推荐通过 ConvertXML 类来调用解析功能:

import convertxml from '@ohos.convertxml';

const converter = new convertxml.ConvertXML();
const result: Object = converter.fastConvertToJSObject(xmlString, options);

其中 options 是一个 ConvertOptions 对象,它控制了两类配置:

  • 行为开关(boolean):是否去除空白、是否忽略属性/注释/CDATA/指令/声明等
  • 输出键名(string):自定义解析结果中各组成部分的 JSON key 名称

fastConvertToJSObject 是自 API 14 以来推荐使用的方法,之前的 convertToJSObjectconvert 方法均已标记为 deprecated。


二、ConvertOptions 详解

ConvertOptions 接口定义了约 18 个属性,下面按用途分类讲解。

2.1 行为开关(7 个 boolean)

属性 类型 默认值 说明
trim boolean false 是否去除文本前后的空白字符
ignoreDeclaration boolean? 是否忽略 XML 声明(<?xml version="1.0"?>
ignoreInstruction boolean? 是否忽略处理指令(<?xxx?>
ignoreAttributes boolean? 是否忽略元素属性
ignoreComment boolean? 是否忽略 XML 注释(<!-- -->
ignoreCDATA boolean? 是否忽略 CDATA 段(<![CDATA[ ]]>
ignoreDoctype boolean? 是否忽略 DOCTYPE 声明

注意:只有 trim必填属性,其余带 ? 的都是可选属性,不传则使用默认行为。

2.2 输出键名(11 个 string)

这些属性让你自定义解析结果中的 key 名称,对于对接不同后端或适配已有代码中的字段名非常有用:

属性 类型 默认值 说明
declarationKey string "declaration" 声明部分的键名
instructionKey string "instruction" 处理指令的键名
attributesKey string "attributes" 元素属性的键名
textKey string "text" 文本内容的键名
cdataKey string "cdata" CDATA 段的键名
doctypeKey string "doctype" DOCTYPE 声明的键名
commentKey string "comment" 注释的键名
parentKey string "parent" 父节点引用的键名
typeKey string "type" 节点类型的键名
nameKey string "name" 节点名称的键名
elementsKey string "elements" 子元素列表的键名

这些键名在 ArkTS 严格模式下也全都是必填属性。实际使用中,保持默认值即可满足绝大多数场景,但了解它们的存在很重要——当你需要把解析结果直接适配某个特定 schema 时,改键名比写映射逻辑更优雅。


三、解析选项的实际效果

光看参数表可能不够直观,下面用一个真实的 XML 片段演示各选项开关后的效果。

3.1 基线:全部关闭(不 trim,不忽略任何内容)

<catalog>
  <!-- 这是一个注释 -->
  <product id="P001">
    <name><![CDATA[iPhone 15 Pro]]></name>
    <price>8999.00</price>
  </product>
</catalog>

所有选项关闭,解析结果完整保留注释、属性、CDATA:

{
  "type": "element",
  "name": "catalog",
  "elements": [
    { "type": "comment", "comment": " 这是一个注释 " },
    {
      "type": "element",
      "name": "product",
      "attributes": { "id": "P001" },
      "elements": [
        {
          "type": "element",
          "name": "name",
          "elements": [{ "type": "cdata", "cdata": "iPhone 15 Pro" }]
        },
        {
          "type": "element",
          "name": "price",
          "elements": [{ "type": "text", "text": "8999.00" }]
        }
      ]
    }
  ]
}

3.2 开启 ignoreComment

注释节点从结果中消失,输出更干净。

3.3 开启 ignoreAttributes

"attributes": { "id": "P001" } 不再出现,只保留元素名称和子节点。

3.4 开启 ignoreCDATA

CDATA 节点被忽略,原本 iPhone 15 Pro 的内容不再出现在输出中。

3.5 开启 trim

所有文本节点前后的空白被去除,处理从 HTML/XML 格式化字符串中提取数据时非常有用。

3.6 开启 ignoreInstruction

处理指令 <?xxx?> 被忽略。在 RSS 场景中,某些 feed 会携带样式表指令 <?xml-stylesheet?>,开启此选项可过滤掉。

这些选项可以组合使用——在实际开发中,根据数据源的特点精确控制解析行为,能省去大量的后处理代码。


在这里插入图片描述
在这里插入图片描述

四、实战:XML 解析实验室

4.1 整体设计

实验室页面包含以下交互区域:

  1. 样本选择区:4 个预设 XML 样本(书店、RSS、配置文件、简单消息),一键切换
  2. XML 输入区:可编辑的 TextArea,支持粘贴自定义 XML
  3. 解析选项区:5 个 Toggle 开关,实时切换解析参数
  4. 结果展示区:Scroll 容器展示格式化 JSON 输出;解析失败时显示红色错误提示

4.2 状态与导入

import { router } from '@kit.ArkUI';
import convertxml from '@ohos.convertxml';
import { FontSize, Spacing } from '../common/Constants';

注意导入方式:import convertxml from '@ohos.convertxml'default import,不是从 @kit.ArkTS 的命名导出。这是因为 @ohos.convertxml 模块导出的是一个 xml 命名空间(namespace),包含 ConvertXML 类和 ConvertOptions 接口。

ConvertOptions 接口在 ArkTS 严格模式下要求定义好所有必填属性。我们的项目中独立声明了 ConvertOpts 接口,保证与 SDK 完全兼容:

interface ConvertOpts {
  trim: boolean;
  ignoreDeclaration: boolean;
  ignoreInstruction: boolean;
  ignoreAttributes: boolean;
  ignoreComment: boolean;
  ignoreCDATA: boolean;
  ignoreDoctype: boolean;
  declarationKey: string;
  instructionKey: string;
  attributesKey: string;
  textKey: string;
  cdataKey: string;
  doctypeKey: string;
  commentKey: string;
  parentKey: string;
  typeKey: string;
  nameKey: string;
  elementsKey: string;
}

页面核心状态:

@State xml: string = '<bookstore>...</bookstore>';
@State jsonOut: string = '';
@State errorMsg: string = '';

@State optTrim: boolean = false;
@State optIgnoreAttrs: boolean = false;
@State optIgnoreComments: boolean = false;
@State optIgnoreCDATA: boolean = false;
@State optIgnoreInstruction: boolean = true; // 默认忽略指令

4.3 核心解析逻辑

private parseXml(): void {
  this.errorMsg = '';
  try {
    const opts: ConvertOpts = {
      trim: this.optTrim,
      ignoreDeclaration: true,
      ignoreInstruction: this.optIgnoreInstruction,
      ignoreAttributes: this.optIgnoreAttrs,
      ignoreComment: this.optIgnoreComments,
      ignoreCDATA: this.optIgnoreCDATA,
      ignoreDoctype: true,
      declarationKey: 'declaration',
      instructionKey: 'instruction',
      attributesKey: 'attributes',
      textKey: 'text',
      cdataKey: 'cdata',
      doctypeKey: 'doctype',
      commentKey: 'comment',
      parentKey: 'parent',
      typeKey: 'type',
      nameKey: 'name',
      elementsKey: 'elements'
    };
    const converter: convertxml.ConvertXML = new convertxml.ConvertXML();
    const result: Object = converter.fastConvertToJSObject(this.xml, opts);
    this.jsonOut = this.toJson(result);
  } catch (e) {
    this.errorMsg = 'XML 解析失败,请检查格式';
    this.jsonOut = '';
  }
}

几点说明:

  1. 实例化 ConvertXMLnew convertxml.ConvertXML() 创建解析器实例,调用 fastConvertToJSObject 执行解析。这和使用静态方法的体验一致,但更符合 API 14+ 的新架构。
  2. try-catch 保护:XML 格式错误时,库会抛出 BusinessError(错误码 10200002),捕获后显示友好提示。
  3. ignoreDeclarationignoreDoctype 固定为 true:实际业务中几乎不需要 XML 声明和 DOCTYPE,所以默认忽略,减少输出噪音。
  4. toJson(obj: Object): string 辅助方法:调用 JSON.stringify(obj, undefined, 2) 输出带缩进的格式化 JSON,方便查看层级结构。

4.4 四个预设样本

private loadSample(type: string): void {
  this.errorMsg = '';
  if (type === 'bookstore') {
    this.xml = '<bookstore>\n  <book category="技术">\n    <title>鸿蒙开发实战</title>\n    <author>张三</author>\n    <price>59.00</price>\n  </book>\n  <book category="文学">\n    <title>江村经济</title>\n    <author>费孝通</author>\n    <price>38.00</price>\n  </book>\n</bookstore>';
  } else if (type === 'rss') {
    this.xml = '<rss version="2.0">\n  <channel>\n    <title>鸿蒙开发者博客</title>\n    <link>https://example.com</link>\n    <description>最新鸿蒙开发资讯</description>\n    <item>\n      <title>ArkUI 声明式开发</title>\n      <pubDate>2026-07-15</pubDate>\n    </item>\n  </channel>\n</rss>';
  } else if (type === 'config') {
    this.xml = '<config>\n  <database>\n    <host>127.0.0.1</host>\n    <port>3306</port>\n    <user>admin</user>\n  </database>\n  <!-- 缓存配置 -->\n  <cache enabled="true">\n    <ttl>3600</ttl>\n  </cache>\n</config>';
  } else {
    this.xml = '<root>\n  <message>Hello 鸿蒙</message>\n  <count>42</count>\n</root>';
  }
  this.parseXml();
}

四个样本覆盖了不同的业务场景:

  • bookstore:多层级嵌套 + 属性(category),演示属性解析
  • rss:标准 RSS 2.0 格式,演示实际数据格式处理
  • config:带注释的配置文件,演示 ignoreComment 效果
  • simple:最简单的 XML,用于理解基础结构

4.5 解析选项 Toggle 控制

5 个 Toggle 开关绑定到 5 个 @State boolean,每次切换立即触发 parseXml()

private options: OptionItem[] = [
  { key: 'optTrim', label: 'trim 去除空白' },
  { key: 'optIgnoreAttrs', label: 'ignoreAttributes 忽略属性' },
  { key: 'optIgnoreComments', label: 'ignoreComment 忽略注释' },
  { key: 'optIgnoreCDATA', label: 'ignoreCDATA 忽略CDATA' },
  { key: 'optIgnoreInstruction', label: 'ignoreInstruction 忽略指令' }
];

在 UI 中使用 ForEach 渲染,每个 Toggle 通过 getOptValue / setOptValue 读写对应的 @State 变量:

Toggle({ type: ToggleType.Switch, isOn: this.getOptValue(opt.key) })
  .selectedColor('#7C3AED')
  .onChange((v: boolean) => {
    this.setOptValue(opt.key, v);
    this.onOptionChange();
  })

getOptValue / setOptValue 通过 if/else 分支映射 key 到具体 @State 变量——在 ArkTS 严格模式下,不能用动态属性名访问 this[key],显式分支是最稳妥的做法。

4.6 结果展示

解析成功时,输出用 fontFamily('monospace') 等宽字体渲染,方便阅读 JSON 结构;解析失败时,显示红色错误卡片:

if (this.errorMsg.length > 0) {
  Text(this.errorMsg)
    .fontColor('#DC2626')
    .backgroundColor('#FEE2E2')
} else {
  Scroll() {
    Text(this.jsonOut)
      .fontSize(12)
      .fontFamily('monospace')
  }
  .height(260)
}

4.7 页面进入时自动解析

aboutToAppear(): void {
  this.parseXml();
}

进入页面即对默认 XML 执行一次解析,用户无需手动触发。


五、几个实战要点与坑

5.1 ConvertXML 类实例化

API 14 开始,推荐使用 new convertxml.ConvertXML() 创建解析器实例,再调用实例方法 fastConvertToJSObject()。旧版的命名空间级函数 convertToJSObjectconvert 已标记 @deprecated since 14,在 API 24 项目中虽然声明文件里还存在,但 ArkTS 严格模式下编译器可能无法正确解析。

正确用法:

const converter: convertxml.ConvertXML = new convertxml.ConvertXML();
const result: Object = converter.fastConvertToJSObject(xml, opts);

错误用法(编译可能失败):

const result = convertxml.convertToJSObject(xml, opts);  // ❌

5.2 ConvertOptions 的完整属性

ArkTS 严格模式要求对象字面量必须对应显式声明的接口或类,且接口中的非可选属性必须全部提供。ConvertOptions 有 18 个属性,其中 trim 和全部 11 个键名属性都是必填的。漏掉任何一个都会触发编译错误 arkts-no-untyped-obj-literals

建议:在项目中声明一个与 SDK 接口完全兼容的 options 接口,每次都传完整属性。键名属性用默认值即可,不影响实际解析语义。

5.3 XML 格式错误处理

当 XML 字符串格式不合法时(比如标签不闭合、属性引号不匹配),fastConvertToJSObject 会抛出 BusinessError,错误码为 10200002。建议始终用 try-catch 包裹解析调用,给用户友好的错误提示。

try {
  const result = converter.fastConvertToJSObject(this.xml, opts);
} catch (e) {
  this.errorMsg = 'XML 解析失败,请检查格式';
}

5.4 忽略声明的默认建议

ignoreDeclaration(XML 声明 <?xml version="1.0"?>)和 ignoreDoctype(DTD 声明)在绝大多数业务场景中都是噪音,建议设为 true。唯一需要声明信息的情况是你要做 XML 格式转换/重写工具,才需要保留。

5.5 ignoreAttributes 对数据完整性的影响

关闭属性解析会让带有属性的元素丢失关键信息。例如:

<product id="P001" category="电子">

开启 ignoreAttributes 后,idcategory 都不会出现在结果中。在处理以属性承载核心数据的 XML(如 SVG、XAML)时,务必保持 ignoreAttributes: false


六、典型应用场景

  • RSS/Atom Feed 解析:读取博客、新闻源的聚合内容,提取标题、链接、发布日期
  • 配置文件解析:处理基于 XML 的服务器配置、数据库连接配置、权限配置等
  • SOAP 接口对接:企业系统的 WebService 接口大多基于 XML,自动解析响应体
  • SVG 元数据提取:读取 SVG 中的图层名、尺寸、关键字等信息
  • 跨平台数据交换:Android/iOS 应用中常见的 XML 数据格式(plist、strings.xml 等),在鸿蒙端直接解析处理
  • 办公文档处理:OOXML 格式(.docx/.xlsx)本质上是 XML,解析 metadata、提取内容等需求可用此 API 作为基础

七、小结

本文以"XML 解析实验室"为载体,系统讲解了 HarmonyOS NEXT 的 @ohos.convertxml

  • 核心 APIConvertXML 类 + fastConvertToJSObject 方法,一行代码将 XML 转为 JS 对象
  • ConvertOptions:7 个行为开关控制解析细节,11 个键名属性定制输出结构
  • 解析选项效果:trim、ignoreComment、ignoreAttributes、ignoreCDATA、ignoreInstruction 各自对输出的影响
  • 工程要点:使用 new ConvertXML() 实例化(非命名空间级函数)、ConvertOptions 必须提供所有必填属性、try-catch 防护 XML 格式错误、根据业务场景选择忽略/保留的内容
  • 实际应用:RSS 解析、配置文件处理、SOAP 接口对接、SVG 元数据提取等

JSON 是数据交换的通用语,但 XML 仍然深深嵌入企业基础设施。@ohos.convertxml 让你不必再纠结于标签和属性,用结构化对象去思考和处理数据——这才是现代开发该有的体验。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐