如何以编程方式使用 VTD-XML 创建 xml?

How to programmatically create xml with VTD-XML?

我想创建一个具有这种形状的 xml,我在循环中插入内部元素 /a/b 并设置元素 b 的属性。

<ROOT>
  <a>
    <b attr1="1" attr2="a"/>
  </a>
  <a>
    <b attr1="1" attr2="b"/>
  </a>
  <a>
    <b attr1="2" attr2="a"/>
  </a>
  <a>
    <b attr1="2" attr2="b"/>
  </a>
</ROOT>

这是我目前的代码:

  public static String createXML(Collection<Integer> numbers, Collection<String> words) {
    String charsetName = "UTF-16";
    byte[] root = "<ROOT></ROOT>".getBytes(charsetName);
    VTDGen vg = new VTDGen();
    AutoPilot ap = new AutoPilot();
    ap.selectXPath("/ROOT");
    XMLModifier xm = new XMLModifier();
    vg.setDoc(root);
    vg.parse(false);
    VTDNav vn = vg.getNav();
    ap.bind(vn);
    xm.bind(vn);

    byte[] aTag = "<a></a>".getBytes(charsetName);
    byte[] bTag = "<b />".getBytes(charsetName);

    int i;

    String collect = numbers.stream().flatMap(number -> words.stream().map(word -> {
      try {
        xm.insertAfterHead(aTag);
        ap.selectXPath("a");
        xm.insertAfterHead(bTag);
        ap.selectXPath("b");
        xm.insertAttribute(String
          .format(" attr1=\"%d\" attr2=\"%s\"",
            number,
            word));
        return xm.outputAndReparse().toNormalizedString(0);
      } catch (ModifyException | NavException | ParseException | IOException | TranscodeException | XPathParseException e) {
        throw new RuntimeException(e);
      }
    }))
      .collect(Collectors.joining(""));

    return collect;
  }

我得到一个 ModifyExcpetion,因为我调用了两次 insertAfterHead。 如何生成所需的 xml 形状?我还不完全明白如何将偏移量放在正确的位置。

我想我可能知道你想要完成什么。有几点建议

  • selectXPath(a) 只是将 xpath 编译成内部格式...它不会为您评估为节点集。要评估它,您需要调用 evalXPath().

  • 您想在根节点下尽可能多地插入单个字符串连接。实际的字符串连接操作应该作为应用逻辑的独立部分出现。在 VTD-XML 中,您考虑位字节、字节数组和 int/long 数组。

下面是我的 mod 你的代码。

public static void main(String[] args) throws VTDException,IOException,
    UnsupportedEncodingException{
        String charsetName = "UTF-16";
        byte[] root = "<ROOT><a><b/></a><a><b/></a><a><b/></a><a><b/></a></ROOT>"
    .getBytes(charsetName); // that is template you want to start with
        VTDGen vg = new VTDGen();
        AutoPilot ap = new AutoPilot();
        ap.selectXPath("/ROOT/a/b");
        XMLModifier xm = new XMLModifier();
        vg.setDoc(root);
        vg.parse(false);
        VTDNav vn = vg.getNav();
        ap.bind(vn);
        xm.bind(vn);
        int i=0;
        int[] ia = new int[4];
        ia[0]=1;ia[1]=1;ia[2]=2;ia[3]=2;
        String[] sa = new String[4];
        sa[0]="a";sa[1]="b";sa[2]="a";sa[3]="b";
        int k=0;
        while((i=ap.evalXPath())!=-1){
            xm.insertAttribute( String.format(" attr1=\"%d\" attr2=\"%s\"",
                    ia[k],
                    sa[k]));
            k++;
        }
        XMLByteOutputStream xbos = new XMLByteOutputStream(xm.getUpdatedDocumentSize());
        xm.output(xbos);
        System.out.println(new String(xbos.getXML(),"UTF-16"));
    }