使用XMLPropertyListConfiguration和XPath修改plist数组元素遇阻求助
问题:使用XPath操作plist数组元素时意外新增属性
测试用plist文件内容:
<?xml version="1.0"?> <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> <plist version="1.0"> <dict> <key>testProp</key> <array> <string>text</string> <string>54</string> <string>2023-11-09T16:29:34Z</string> </array> <key>objectProp</key> <array> <string>text</string> <integer>54</integer> <date>2023-11-09T16:29:34Z</date> </array> </dict> </plist>
构建XMLPropertyListConfiguration的代码:
File file = new File("path/to/config.plist"); XMLPropertyListConfiguration configuration = new FileBasedConfigurationBuilder<>(XMLPropertyListConfiguration.class) .configure(new Parameters().xml() .setFile(file) .setExpressionEngine(new XPathExpressionEngine())) .getConfiguration(); // 修改后保存 FileHandler handler = new FileHandler(configuration); handler.save(file);
尝试调用configuration.setProperty("/testProp[2]", "a different string")修改testProp数组的第二个元素,结果却新增了名为testProp[2]的独立属性,希望找到正确的操作方式,优先使用XPath,也接受单独处理数组的方案。
原因分析
你的XPath表达式写法错误:在plist的XML结构中,testProp是<key>元素的文本内容,并非节点名称。直接用/testProp[2]无法定位到数组元素,引擎会将其识别为新的属性键名,从而创建独立属性。
解决方案1:使用正确的XPath定位数组元素
要准确修改testProp数组的第二个元素(XPath索引从1开始),可以使用以下XPath表达式:
/plist/dict/array[preceding-sibling::key[normalize-space(text())='testProp']]/string[2]
调用示例:
// 修改testProp数组的第二个元素 configuration.setProperty( "/plist/dict/array[preceding-sibling::key[normalize-space(text())='testProp']]/string[2]", "a different string" );
如果要修改objectProp数组的第二个整数元素,对应的XPath为:
/plist/dict/array[preceding-sibling::key[normalize-space(text())='objectProp']]/integer[2]
解决方案2:读取数组为List修改后写回
如果觉得XPath语法繁琐,可以直接将数组读取为List,修改后重新写入配置,这种方式更直观,适合复杂操作(如插入元素):
修改数组元素
// 读取testProp数组为List(Java索引从0开始) List<String> testPropList = configuration.getList(String.class, "testProp"); // 修改第二个元素 testPropList.set(1, "a different string"); // 将修改后的List写回配置 configuration.setProperty("testProp", testPropList);
插入新元素到数组
// 在testProp数组的第二个位置插入新元素 testPropList.add(1, "inserted new string"); configuration.setProperty("testProp", testPropList);
内容的提问来源于stack exchange,提问作者EarthTurtle
相关产品推荐
相关产品推荐

