1

我正在使用 VTD-XML 来更新 XML 文件。在这方面,我试图获得一种灵活的方式来维护元素的属性。因此,如果我的原始元素是:

<MyElement name="myName" existattr="orig" />

我希望能够将其更新为:

<MyElement name="myName" existattr="new" newattr="newValue" />

我正在使用 Map 来管理代码中的属性/值对,当我更新 XML 时,我正在执行以下操作:

private XMLModifier xm = new XMLModifier();
xm.bind(vn);

for (String key : attr.keySet()) {
     int i = vn.getAttrVal(key);

     if (i!=-1) {
         xm.updateToken(i, attr.get(key));
     } else {
         xm.insertAttribute(key+"='"+attr.get(key)+"'");
     }
}
vn = xm.outputAndReparse();

这适用于更新现有属性,但是当属性不存在时,它会命中插入(insertAttribute)并且我得到“ModifyException”

com.ximpleware.ModifyException: There can be only one insert per offset
at com.ximpleware.XMLModifier.insertBytesAt(XMLModifier.java:341)
at com.ximpleware.XMLModifier.insertAttribute(XMLModifier.java:1833)

我的猜测是,由于我没有直接操作偏移量,因此这可能是意料之中的。但是,我看不到在元素中的某个位置(最后)插入属性的功能。

我的怀疑是我需要在“偏移”级别使用 xm.insertBytesAt(int offset, byte[] content) 之类的东西 - 因为这是我需要进入的领域,但有没有办法计算我可以插入的偏移量(就在标签末尾之前)?

当然,我可能在这里以某种方式误用了 VTD——如果有更好的方法来实现这一点,那么很高兴被指导。

谢谢

4

1 回答 1

2

这是我还没有遇到的 API 的一个有趣的限制。如果 vtd-xml-author 能够详细说明技术细节以及存在此限制的原因,那就太好了。

作为您的问题的解决方案,一种简单的方法是累积要作为字符串插入的键值对,然后在 for 循环终止后将它们插入到单个调用中。

我已经测试过这可以按照您的代码工作:

private XMLModifier xm_ = new XMLModifier();
xm.bind(vn);

String insertedAttributes = "";
for (String key : attr.keySet()) {
     int i = vn.getAttrVal(key);

     if (i!=-1) {
         xm.updateToken(i, attr.get(key));
     } else {
         // Store the key-values to be inserted as attributes
         insertedAttributes += " " + key + "='" + attr.get(key) + "'";
     }
}
if (!insertedAttributes.equals("")) {
   // Insert attributes only once
   xm.insertAttribute(insertedAttributes);
}

如果您需要更新多个元素的属性,这也将起作用,只需将上述代码嵌套在其中 while(autoPilot.evalXPath() != -1)并确保insertedAttributes = "";在每个 while 循环的末尾进行设置。

希望这可以帮助。

于 2013-07-10T06:57:56.723 回答