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)));
csoundAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

objectsCommented:
ByteArrayOutputStream bout = new ByteArrayOutputStream();
t.transform(new DOMSource(doc), new StreamResult(bout));
bout.close();
String xmlout = bout.toString();
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.