在VTD-XML中如何使用现有属性将新属性添加到标记中?

时间:2013-07-04 12:56:48

标签: vtd-xml

我正在使用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 - 如果有更好的方法来实现这一点,那么很高兴被指导。

由于

1 个答案:

答案 0 :(得分:2)

这是我尚未遇到的API的有趣限制。如果vtd-xml-author可以详细说明技术细节以及为什么存在这种限制,那将是很好的。

作为问题的解决方案,一个简单的方法是累积要作为String插入的键值对,然后在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)中,并确保在每个while循环结束时设置insertedAttributes = "";,这也会有效。

希望这有帮助。