Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
只需知道标记名和缩进即可生成xml(在描述时解释)-Java_Java_Xml - Fatal编程技术网

只需知道标记名和缩进即可生成xml(在描述时解释)-Java

只需知道标记名和缩进即可生成xml(在描述时解释)-Java,java,xml,Java,Xml,我有两个列表,大小相等。第一个列表包含所有需要生成的xml标记名,第二个列表包含它们的缩进(找不到更好的词)。例如,缩进:根元素有缩进0,其子元素有缩进1,依此类推 更好的例子是: XML TAGS | INDENT root | 0 child1 | 1 child12 | 2 child2 | 1 child22 | 2 XML示例: <root> <child1> <child12></ch

我有两个列表,大小相等。第一个列表包含所有需要生成的xml标记名,第二个列表包含它们的缩进(找不到更好的词)。例如,缩进:根元素有缩进0,其子元素有缩进1,依此类推

更好的例子是:

XML TAGS  |  INDENT
root      |  0
child1    |  1
child12   |  2
child2    |  1
child22   |  2
XML示例:

<root>
  <child1>
    <child12></child12>
  </child1>
  <child2>
    <child22></child22>
  </child2>
</root>

我的做法:

private static void generateXML() throws ParserConfigurationException, TransformerException {

    if (xmlNames.size() == indentationNumbers.size()) {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.newDocument();

        // root element
        Element root = document.createElement(xmlNames.get(0));
        document.appendChild(root);
        int lastKnownIndentation = Integer.parseInt(indentationNumbers.get(0));

        loopThroughLists(document, lastKnownIndentation, root);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(System.out);

        transformer.transform(source, result);

    } else {
        // TODO Logger + Exception
    }
}


private static void loopThroughLists(Document document, int lastKnownIndentation, Element root) {

    for (int i = 1; i < xmlNames.size(); i++) {

        String xmlName = xmlNames.get(i);
        int indentaion = Integer.parseInt(indentationNumbers.get(i));
        Element element = null;

        if (xmlName.startsWith("@")) {
            continue;
        }

        if (indentaion == lastKnownIndentation + 1) {
            element = document.createElement(xmlName);
            root.appendChild(element);
        } else {
            loopThroughLists(document, indentaion, element);
        }
    }
}
private static void generateXML()抛出ParserConfiguration异常,TransformerException{
if(xmlNames.size()==indicationnumbers.size()){
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
DocumentBuilder=factory.newDocumentBuilder();
Document Document=builder.newDocument();
//根元素
元素根=document.createElement(xmlNames.get(0));
document.appendChild(根);
int lastKnownIndentation=Integer.parseInt(indentationNumbers.get(0));
循环列表(文档、lastKnownIndentation、根目录);
TransformerFactory TransformerFactory=TransformerFactory.newInstance();
Transformer Transformer=transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT,“是”);
transformer.setOutputProperty(“{http://xml.apache.org/xslt}缩进金额,“2”);
DOMSource=新的DOMSource(文档);
StreamResult结果=新的StreamResult(System.out);
变换(源、结果);
}否则{
//TODO记录器+异常
}
}
私有静态void loopThroughLists(文档文档,int-lastKnownIndentation,元素根){
对于(int i=1;i
我试图使用递归来生成基于缩进的xml(如前所述),但我总是得到一个StackOverflower错误,我知道这意味着什么,我知道我在列表中循环错误。你能帮我找个更好的方法吗


提前感谢

您可以使用lexer和parser生成器实现一个解决方案

最近,我与和一起朝着这个方向做了一些事情

优点:

  • 错误检测
  • 您可以扩展输入和输出
  • 这是一个典型的编译器问题(IMHO)
缺点:

  • 学习编译器构造
  • 学习使用新工具
  • 问题可能太小,无法使此解决方案可行

始终在
loopThroughLists
函数的索引1处启动循环。这意味着您每次都使用标记名
child1
。我从索引1开始,因为我在
循环列表之前创建了位于索引0的根元素,我知道,不从0开始是正确的。每次递归调用函数时,都从1开始,而不是从下一个标记开始。下面的代码块一直在执行..else{loopThroughLists(document,indentaion,element);}为了了解更多信息。我需要将开始索引传递给函数,所以当递归调用发生时,它应该从前面左边的索引开始,对吗?