I need to implement a visual force page which contains two inputTextArea boxes. These textboxes should form like one box is left side for input and another one is right side to display result. This page also should contains a button.
The input and output will be like below.
Input:
Input text box will take Xml document as input
Output:
output need to be display like XML root elements, child elements names, child elements vales and attributes names and their vales if they have attributes by clicking on button.
To get this requirement, i have implemented the following class and Visual force page. These are working in successive way except the one case. The only case is, if i give a xml, the output is coming like below which is shown in image.
I need to remove the empty space between Element Name:book, Element Value:, Attribute Name: id which means the result should be come like below.
XML format should follow a format like shown images. It should not follow any other way.
I have tried a lot to remove the space between elements. But, i couldn't get it. Can anyone please help me to get out of this problem.
Please find the VF Page and class:
VF Page:
<apex:page controller="ParseTest3">
<apex:form >
<apex:pageBlock id="refresh">
<apex:pageMessages />
<apex:inputTextarea style="width:300px;height:300px;" value="{!parsingXmlFile}"/>
<apex:inputTextarea style="width:300px;height:300px;" value="{!resultFile}" />
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="Parse the file" reRender="refresh" action="{!parseFile}"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>
Class:
public class ParseTest3 {
public String parsingXmlFile{set;get;}
public String resultFile{set;get;}
public void parseFile(){
Dom.Document doc = new Dom.Document();
doc.load(parsingXmlFile);
Dom.XmlNode node = doc.getRootElement();
resultFile = 'Root Element: '+node.getName();
if(node.getAttributeCount() > 0) {
for(integer i=0; i< node.getAttributeCount() ;i++) {
resultFile += '\nAttribute Name: '+node.getAttributeKeyAt(i)+'\nAttribute Value: '+node.getAttributeValue(node.getAttributeKeyAt(i), null);
}
}
for(Dom.XmlNode xnode : node.getChildElements()) {
resultFile +='\nElement Name:'+xnode.getName()+'\nElement Value:'+xnode.getText();
if(xnode.getAttributeCount() > 0) {
for(integer i=0; i< xnode.getAttributeCount() ;i++) {
resultFile += '\nAttribute Name: '+xnode.getAttributeKeyAt(i)+'\nAttribute Value: '+xnode.getAttributeValue(xnode.getAttributeKeyAt(i), null);
}
}
for(Dom.XmlNode axnode : xnode.getChildElements()) {
resultFile +='\nElement Name:'+axnode.getName()+'\nElement Value:'+axnode.getText();
if(String.isNotBlank(axnode.getNamespace()))
resultFile += '\nName Space: '+axnode.getNamespace();
if(axnode.getAttributeCount() > 0) {
for(integer i=0; i< axnode.getAttributeCount() ;i++) {
resultFile += '\nAttribute Name: '+axnode.getAttributeKeyAt(i)+'\nAttribute Value: '+axnode.getAttributeValue(axnode.getAttributeKeyAt(i), null);
}
}
}
}
}
}
Any help is appreciated.
Best Answer
You should check if the element has any value before appending it to your
resultFile
.Change this:
'\nElement Value:'+xnode.getText();
To:
(String.isBlank(xnode.getText()) ? '' :'\nElement Value:'+xnode.getText());
So your controller would now look like this:
One more thing. Your current solution will work for XML files that are only 2 levels deep. I'd suggest to change it up a little bit so that it uses a recursive function:
Now your controller will be able to parse any XML string you pass to it, and you won't have to add additional nested
for loops
to parse additional levels of XML nodes.