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)

私の推測では、オフセットを直接操作していないので、これは予想されることです。ただし、要素内の位置 (最後) に an 属性を挿入する機能はありません。

私の疑いは、 xm.insertBytesAt(int offset, byte[] content) のようなものを使用して「オフセット」レベルでそれを行う必要があるということです-これは私が入る必要のある領域であるため、まだ計算する方法はありますか挿入できるオフセット (タグの末尾の直前)?

もちろん、私はここで VTD を何らかの形で誤用している可能性があります。これを達成するためのより良い方法があれば、喜んで指示されます。

ありがとう

4

1 に答える 1

2

これは、私がまだ遭遇したことのない API の興味深い制限です。vtd-xml-author が技術的な詳細と、この制限が存在する理由について詳しく説明できれば幸いです。

問題の解決策として、簡単な方法は、キーと値のペアを蓄積して文字列として挿入し、for ループが終了した後にそれらを 1 回の呼び出しで挿入することです。

これがあなたのコードに従って機能することをテストしました:

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 ループの最後にwhile(autoPilot.evalXPath() != -1)必ず設定してください。insertedAttributes = "";

お役に立てれば。

于 2013-07-10T06:57:56.723 に答える