0

I need to make a convertion like this:

given (one of many):

    <Field name="topmostSubform[0].Page1[0].MemberID[0]" value="025620451" />

I need to convert it to an xml like this:

<?xml version="1.0" encoding="UTF-8"?>
<topmostSubform ind="0">
     <page ind ="0">
         <MemeberID ind="0">025620451</MemeberID>
     </page>
</topmostSubform>

I get a whole bunch of fields like in the example that i need to convert to one xml.

The field tag can contain more tags then the example.

What approach do you suggest?

the difficulty is what datastructure to use? how can i fill this database so eventually i can create an xml out of it?

I tried building the xml using DOM while iterating the input, but in that case i created lots of duplicated tags.

Thanks.

4

1 回答 1

1

检查元素是否已存在的 xpath 和递归的组合将满足您的需求。

这就是我想出的:

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Transformation 
{
  private static final XPath XPATH = XPathFactory.newInstance().newXPath();

  public static void main(String[] args) 
  {
    try 
    {
      DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

      Document xml1 = documentBuilder.parse(new ByteArrayInputStream("<Field name=\"topmostSubform[0].Page[0].MemberID[0]\" value=\"1\"/>".getBytes()));
      Document xml2 = documentBuilder.parse(new ByteArrayInputStream("<Field name=\"topmostSubform[0].Page[0].MemberID[1]\" value=\"2\"/>".getBytes()));
      Document xml3 = documentBuilder.parse(new ByteArrayInputStream("<Field name=\"topmostSubform[0].Page[1].MemberID[0]\" value=\"3\"/>".getBytes()));
      Document xml4 = documentBuilder.parse(new ByteArrayInputStream("<Field name=\"topmostSubform[1].Page[0].MemberID[0]\" value=\"4\"/>".getBytes()));

      Document document = documentBuilder.newDocument();
      document.appendChild(document.createElement("root"));

      //Loop through each piece of XML creating elements in the single document as necessary.
      for (Document xml : new Document[]{xml1, xml2, xml3, xml4}) 
      {
        Element fieldElement = (Element)XPATH.evaluate("/Field", xml, XPathConstants.NODE);

        String name = fieldElement.getAttribute("name");
        String value = fieldElement.getAttribute("value");

        createElements(
          document, 
          document.getDocumentElement(), 
          new ArrayList<String>(Arrays.asList(name.split("\\."))), 
          value
        );
      }

      //Print the result at the command line.
      Transformer transformer = TransformerFactory.newInstance().newTransformer();
      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

      StringWriter writer = new StringWriter();
      transformer.transform(new DOMSource(document), new StreamResult(writer));

      System.out.println(writer.getBuffer().toString());
    }
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }

  /**
   * Creates child elements under the <code>parent</code> based on the <code>nameTokens</code>.
   */
  private static void createElements(Document document, Element parent, List<String> nameTokens, String value) throws XPathExpressionException 
  {
    String nameToken = nameTokens.remove(0);

    String name = nameToken.substring(0, nameToken.indexOf("["));
    String index = nameToken.substring(nameToken.indexOf("[") + 1, nameToken.indexOf("]"));

    Element element = (Element)XPATH.evaluate(name + "[@ind=" + index + "]", parent, XPathConstants.NODE);
    if (element == null) 
    {
      element = document.createElement(name);
      element.setAttribute("ind", index);
      parent.appendChild(element);
    }

    if (nameTokens.isEmpty()) 
    {
      element.appendChild(document.createTextNode(value));
    }
    else 
    {
      createElements(document, element, nameTokens, value);
    }
  }
}

哪个(格式化后)打印:

<root>
  <topmostSubform ind="0">
    <Page ind="0">
      <MemberID ind="0">1</MemberID>
      <MemberID ind="1">2</MemberID>
    </Page>
    <Page ind="1">
      <MemberID ind="0">3</MemberID>
    </Page>
  </topmostSubform>
    <topmostSubform ind="1">
      <Page ind="0">
        <MemberID ind="0">4</MemberID>
      </Page>
    </topmostSubform>
 </root>
于 2013-04-29T16:24:13.067 回答