PAYATHON 2026

如何在 MATLAB 中使用 XML 文件按数字查找对应标签?

技术老齐

先用 xmlread 读取 XML,将数字和标签的对应关系存入 containers.Map,再遍历数字数组,逐个取出标签。这样只需解析一次 XML,后续查询都通过映射表完成。

具体写法取决于 XML 的结构。这里没有实际文件,示例假设数字保存在 id 属性中,标签文本保存在 label 属性中。

1. 准备 XML 文件

将以下内容保存为 lookup.xml,放在 MATLAB 当前文件夹中:

<?xml version="1.0" encoding="UTF-8"?>
<lookup>
    <item id="10" label="Apple"/>
    <item id="20" label="Banana"/>
    <item id="30" label="Orange"/>
</lookup>

其中:

  • lookup 是根元素,包含所有记录。
  • 每个 item 元素是一条记录。
  • id="10" 表示查找用的数字,label="Apple" 是对应的文本。

XML 属性值都是文本,读取 id 后需要将其转换为 MATLAB 数值。

2. 读取 XML 并建立查找表

以下代码使用 xmlread 返回的 Java DOM 接口,MATLAB 环境需要支持该接口并启用 JVM。

% 读取 XML 文件
doc = xmlread('lookup.xml');

% 获取所有名为 item 的元素
items = doc.getElementsByTagName('item');

% 创建查找表:键为 double,值为字符向量
lookup = containers.Map('KeyType', 'double', 'ValueType', 'char');

for i = 0:(items.getLength() - 1)
    node = items.item(i);

    % 检查每条记录是否包含所需属性
    if ~node.hasAttribute('id') || ~node.hasAttribute('label')
        error('第 %d 条记录缺少 id 或 label 属性。', i + 1);
    end

    % 将 XML 属性转换为 MATLAB 数据
    idText = char(node.getAttribute('id'));
    id = str2double(idText);
    label = char(node.getAttribute('label'));

    if ~isfinite(id)
        error('第 %d 条记录的 id 不是有效的有限数值。', i + 1);
    end

    % 每个数字只能对应一个标签
    if isKey(lookup, id)
        error('XML 中存在重复的 id:%g。', id);
    end

    lookup(id) = label;
end

doc 是 XML 文档的 DOM 对象,可以理解为一棵由元素和属性组成的树。getElementsByTagName('item') 会找到文档中所有名为 item 的元素,也包括嵌套在其他元素中的记录。

DOM 的 item(i) 从 0 开始编号,MATLAB 数组通常从 1 开始编号,因此这里的循环范围是 0 到 getLength()-1。

查找表建好后,可以直接查询单个数字:

lookup(20)

示例中的查询结果是 'Banana'。

3. 根据数字数组获取标签

假设要查询的数字数组为:

numbers = [20 10 30 20];

按数组原有顺序逐个查找:

labels = cell(size(numbers));

for k = 1:numel(numbers)
    id = numbers(k);

    if ~isKey(lookup, id)
        error('查找表中没有数字 %g。', id);
    end

    labels{k} = lookup(id);
end

disp(labels);

得到的 labels 为:

{'Banana', 'Apple', 'Orange', 'Banana'}

不同标签的长度可以不同,因此这里用元胞数组 cell 保存文本。labels{k} 用于取出第 k 个元胞中的标签,例如:

labels{1}

结果是 'Banana'。

cell(size(numbers)) 会保留输入数组的形状。如果 numbers 是列向量,结果也是列形式的元胞数组。

4. XML 结构不同时,如何修改代码?

如果数字和标签保存在子元素中,例如:

<lookup>
    <item>
        <id>10</id>
        <label>Apple</label>
    </item>
</lookup>

就需要读取元素的文本内容。假设每个 item 中恰好有一个 id 和一个 label,将前面循环中检查和读取属性的部分替换为:

idNodes = node.getElementsByTagName('id');
labelNodes = node.getElementsByTagName('label');

if idNodes.getLength() ~= 1 || labelNodes.getLength() ~= 1
    error('每条 item 记录必须包含一个 id 和一个 label 元素。');
end

idNode = idNodes.item(0);
labelNode = labelNodes.item(0);

id = str2double(char(idNode.getTextContent()));
label = strtrim(char(labelNode.getTextContent()));

后面的数值检查、重复检查和 lookup(id) = label 保持原样。strtrim 会去掉标签文本两端的空白;如果这些空白有实际含义,应去掉这次 strtrim 调用。

标签文本和 XML 元素名也要区分。在 <item id="10" label="Apple"/> 中,元素名是 item,标签文本是 Apple。如果需要获取元素名,可以使用:

elementName = char(node.getNodeName());

5. 使用时需要注意什么?

  • 文件不在当前文件夹时,向 xmlread 传入正确的相对路径或完整路径。可以用 pwd 查看当前文件夹。
  • XML 名称区分大小写,item 和 Item 是不同的元素名。对于带命名空间的 XML,需要相应调整节点选择方式。
  • 示例要求每个数字只对应一个标签,遇到重复 id 会报错。如果一个数字可以对应多个标签,需要改用能保存多个值的数据结构。
  • 输入数字不在查找表中时,代码会停止并报错。如果希望继续处理,可以将对应的 labels{k} 设为 '',再用 continue 跳过本次查询。
  • 数值键按精确值匹配。浮点计算结果可能与 XML 中的数值有微小差异,需要按业务规则统一精度。
  • 如果编号中的前导零有意义,例如 "0010" 与 "10" 必须区分,应使用文本键。超过 double 精确整数表示范围的长编号也应保留为文本。

备注:内容仅供参考。