Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 437
  • Last Modified:

XML

Can anyone please tell me how to convert from Document to String in XML? I know t.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(file))); will will output the result into a file but how can I get a String result without writing on to  the file?

Also, when I am writing XML to a file I am specifiying DTD in absolute path like

File dsystem=new File("."+sp+"xml"+sp+"symbol.dtd");
     t.setOutputProperty("doctype-system",
                   "file://"+sp+sp+dsystem.getCanonicalPath()
                   );

but when I move the program to  different directory, the program can not locate the DTD file. Does anyone have any idea how to overcome this problem?

Thanx

Document doc = buildDocument();
     
     Transformer t = TransformerFactory
            .newInstance().newTransformer();
            String sp=File.separator;
File dsystem=new File("."+sp+"xml"+sp+"symbol.dtd");
     t.setOutputProperty("doctype-system",
                   "file://"+sp+sp+dsystem.getCanonicalPath()
                   );

     t.transform(new DOMSource(doc),
              new StreamResult(new FileOutputStream(file)));
0
csound
Asked:
csound
  • 8
  • 6
  • 3
  • +1
1 Solution
 
objectsCommented:
ByteArrayOutputStream bout = new ByteArrayOutputStream();
t.transform(new DOMSource(doc), new StreamResult(bout));
bout.close();
String xmlout = bout.toString();
0
 
csoundAuthor Commented:
->objects
Thanks for your comment but do  you know the answer for the second part of the question?

Thanx
0
 
girionisCommented:
 For the second part you need the file in format:

  file://C/dtdfile.dtd

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
csoundAuthor Commented:
Yes I know that. My question is that if another user reads the Xml file in a different computer, the program would not able to read it if there isn't the DTD file in the directory specified.  Likewise, even if we specify the location of the DTD within the program directory, like what i did, if we move the program to a different directory then, again the program would not able to find the DTD file specified.

P.S
I made a small mistake in my program
  t.setOutputProperty("doctype-system",
                  "file://"+dsystem.getCanonicalPath()
                  );
0
 
girionisCommented:
 Why don't you have the DTD somewher on the webserver then and people can access it from wherever they are?
0
 
CEHJCommented:
1. Use
StringWriter sw = new StringWriter();
t.transform(new DOMSource(doc),new StreamResult(sw));
String doc = sw.toString();

2. You can resolve the DTD using setEntityResolver on your reader, allowing you to alter the location of the DTD, but you should prefer the principle of gironis' suggestion.
0
 
csoundAuthor Commented:
->girionis
But then computers need to be connected to the Internet when using the program.
0
 
CEHJCommented:
True
0
 
girionisCommented:
> But then computers need to be connected to the Internet when using the program.

  Yes. If not try CEHJ's approach.
0
 
CEHJCommented:
Why not jar up the DTD with the program and use my second suggestion? That way, it'll always be there.
0
 
csoundAuthor Commented:
->CEHJ
This is my code to parse XML file.

DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();


Document doc = builder.parse(file);
     
So, if I have the DTD file in the directory, say "C:/test.dtd", what can I put for the argument for the setEntityResolver method?  

builder.setEntityResolver(?):


0
 
CEHJCommented:
Here's something i found showing how it's set:

import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import java.io.PrintWriter;

public class Test {

  public static void main(String[] args) {
    try {
      DOMParser parser = new DOMParser();
      parser.parse(new InputSource(args[0]));
      parser.setEntityResolver(XmlUtils.getLocalEntityResolver());
      Document doc = parser.getDocument();
      NodeList images = doc.getElementsByTagName("img");
      processNodeList(images);
      XmlUtils.serializeXhtml(doc,"new-q.htm");

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  static void processNodeList(NodeList nodes){
    for(int i= 0;i < nodes.getLength();i++){
      Element elem = (Element) nodes.item(i);
      if (elem.getAttribute("src").equals("qbtn1.gif")) {
        elem.setAttribute("alt","question");
      }
    }
  }


}

0
 
csoundAuthor Commented:
->In your case, you need
http://java.sun.com/j2se/1.4/docs/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver(org.xml.sax.EntityResolver) 

yes I knew that
->builder.setEntityResolver(?):

but I didn't know what to pass in this method. From the API I know I have to pass EntityResolver but I got confused here. With the example I wrote before, what kind of EntityResolver should I use? it would be great if you could provide me some codes. Thanx

->So, if I have the DTD file in the directory, -say "C:/test.dtd", what can I put for the argument for the setEntityResolver method?  

0
 
CEHJCommented:
I'll have a look. I think i wrote a util somewhere...
0
 
CEHJCommented:
Here we are - an inner class of a utility class i wrote. In your case, you'd maybe want to open a stream on the DTD inside the jar:

/**
   * Allows system ids in doctype declarations to be read locally.
   * In this case, we get system id from the current directory
   *
   * @author     protean
   * @created    26 July 2002
   */
  private static class LocalEntityResolver implements org.xml.sax.EntityResolver {

    /**
     *Description of the Method
     *
     * @param  publicId  Public id of DTD
     * @param  systemId  System id of DTD
     * @return           An input source opened on the local DTD
     */
    public org.xml.sax.InputSource resolveEntity(String publicId, String systemId) {
      try {
        String localId = "./" + systemId.substring(systemId.lastIndexOf("/") + 1);
        //DEBUG

        //System.out.println("Resolved entity " + systemId);
        //System.out.println("To " + localId);
        return new org.xml.sax.InputSource(new java.io.FileReader(localId));
      } catch (java.io.IOException e) {
        e.printStackTrace();
        return null;
      }

    }

  }
0
 
CEHJCommented:
Incidentally, one of the reasons i wrote that was so i didn't have to be connected to the network to get the DTD ;-)
0
 
csoundAuthor Commented:
->object
Thanx for your help.

->CEHJ
Thanx for your help. Please find a question titled "To CEHJ". I will give some points there. =)
0
 
objectsCommented:
Thanks for the points :)
0

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

  • 8
  • 6
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now