我有一个包含XML的Java字符串,没有换行或缩进。我想把它变成一个字符串与格式良好的XML。我怎么做呢?
String unformattedXml = "<tag><nested>hello</nested></tag>";
String formattedXml = new [UnknownClass]().format(unformattedXml);
注意:我的输入是一个字符串。输出是一个字符串。
(基本)模拟结果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag>
<nested>hello</nested>
</tag>
</root>
在提出我自己的解决方案之前,我应该先看看这一页!不管怎样,我使用Java递归来解析xml页面。此代码是完全自包含的,不依赖于第三方库。也. .它使用递归!
// you call this method passing in the xml text
public static void prettyPrint(String text){
prettyPrint(text, 0);
}
// "index" corresponds to the number of levels of nesting and/or the number of tabs to print before printing the tag
public static void prettyPrint(String xmlText, int index){
boolean foundTagStart = false;
StringBuilder tagChars = new StringBuilder();
String startTag = "";
String endTag = "";
String[] chars = xmlText.split("");
// find the next start tag
for(String ch : chars){
if(ch.equalsIgnoreCase("<")){
tagChars.append(ch);
foundTagStart = true;
} else if(ch.equalsIgnoreCase(">") && foundTagStart){
startTag = tagChars.append(ch).toString();
String tempTag = startTag;
endTag = (tempTag.contains("\"") ? (tempTag.split(" ")[0] + ">") : tempTag).replace("<", "</"); // <startTag attr1=1 attr2=2> => </startTag>
break;
} else if(foundTagStart){
tagChars.append(ch);
}
}
// once start and end tag are calculated, print start tag, then content, then end tag
if(foundTagStart){
int startIndex = xmlText.indexOf(startTag);
int endIndex = xmlText.indexOf(endTag);
// handle if matching tags NOT found
if((startIndex < 0) || (endIndex < 0)){
if(startIndex < 0) {
// no start tag found
return;
} else {
// start tag found, no end tag found (handles single tags aka "<mytag/>" or "<?xml ...>")
printTabs(index);
System.out.println(startTag);
// move on to the next tag
// NOTE: "index" (not index+1) because next tag is on same level as this one
prettyPrint(xmlText.substring(startIndex+startTag.length(), xmlText.length()), index);
return;
}
// handle when matching tags found
} else {
String content = xmlText.substring(startIndex+startTag.length(), endIndex);
boolean isTagContainsTags = content.contains("<"); // content contains tags
printTabs(index);
if(isTagContainsTags){ // ie: <tag1><tag2>stuff</tag2></tag1>
System.out.println(startTag);
prettyPrint(content, index+1); // "index+1" because "content" is nested
printTabs(index);
} else {
System.out.print(startTag); // ie: <tag1>stuff</tag1> or <tag1></tag1>
System.out.print(content);
}
System.out.println(endTag);
int nextIndex = endIndex + endTag.length();
if(xmlText.length() > nextIndex){ // if there are more tags on this level, continue
prettyPrint(xmlText.substring(nextIndex, xmlText.length()), index);
}
}
} else {
System.out.print(xmlText);
}
}
private static void printTabs(int counter){
while(counter-- > 0){
System.out.print("\t");
}
}