我正在使用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 - 如果有更好的方法来实现这一点,那么很高兴被指导。
由于
答案 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 = "";
,这也会有效。
希望这有帮助。