Writing XML in General

Ok so I am new to this idea. I was wondering can anyone tell me where I can find a good example of Java writing XML using the DOM model.
I cannot figure out how to output my XML Document to a file.

Ok, is there anyway to get the file to be in better XML format? Currently everything is ouput as one long string
Something like this
<?xml version="1.0" encoding="UTF-8"?><Top The="Attrbiute For Top"><Next><Last An="Element for this Last">I am a TextNode</Last><Last>I am a TextNode as Well</Last></Next></Top>I want it to appear like this
<?xml version="1.0" encoding="UTF-8"?>
<Top The="Attrbiute For Top">
     <Next>
          <Last An="Element for this Last">I am a TextNode</Last>
          <Last>I am a TextNode as Well</Last>
     </Next>
</Top>

Similar Messages

  • "encoding = UTF-8" missing while writing XML file using file Adapter

    Hi,
    We are facing an unique problem writing xml file using file adapter. The file is coming without the encoding part in the header of xml. An excerpt of the file that is getting generated:
    <?xml version="1.0" ?>
    <customerSet>
    <user>
    <externalID>51017</externalID>
    <userInfo>
    <employeeID>51017</employeeID>
    <employeeType>Contractor</employeeType>
    <userName/>
    <firstName>Gail</firstName>
    <lastName>Mikasa</lastName>
    <email>[email protected]</email>
    <costCenter>8506</costCenter>
    <departmentCode/>
    <departmentName>1200 Corp IT Exec 8506</departmentName>
    <businessUnit>1200</businessUnit>
    <jobTitle>HR Analyst 4</jobTitle>
    <managerID>49541</managerID>
    <division>290</division>
    <companyName>HQ-Milpitas, US</companyName>
    <workphone>
    <number/>
    </workphone>
    <mobilePhone>
    <number/>
    </customerSet>
    </user>
    So if you see the header the "encoding=UTF-8" is missing after "version-1.0".
    Do we need to configure any properties in File Adapter?? Or is it the standard way of rendering by the adapter.
    Please advice.
    Thanks in advance!!!

    System.out.println(nodeList.item(0).getFirstChild().getNodeValue());

  • Writing XML files

    Hello all
    There's a vast amount of information on the java.sun.com site about parsing XML files:
    * creating DOM trees in memory from an XML file
    * setting up event handlers to be called when an XML file is parsed
    * transforming XML files using XSL.
    However, I can find very little information anywhere about writing XML files in the first place! I'm already aware of two ways to do this:
    (1) create a DOM in memory and write this to a file. If the data is large, though, this isn't feasible.
    (2) just output the XML elements directly to some file as text. This doesn't take account of the encoding, or special characters, and the document is not necessarily then syntactically valid.
    Is there some API which I haven't yet come across that is designed specifically for writing XML data to files? If it's built in to Java 2, then goodness knows how I've missed it all this time; if it's third-party, I'd be grateful for any links.
    Thanks for your help
    Rich Fearn

    I know pastes can be horrible, but this is a working example which I find useful: SAX XML output ;)
    import java.io.*;
    // SAX classes.
    import org.xml.sax.*;
    import org.xml.sax.helpers.*;
    //JAXP 1.1
    import javax.xml.parsers.*;
    import javax.xml.transform.*;
    import javax.xml.transform.stream.*;
    import javax.xml.transform.sax.*;
                    //AlphabetXMLOut(file, alphabets);
    class AlphabetXMLOut {
            public void run(){
                    try{
                            FileOutputStream fos = new FileOutputStream("output.xml");
                            PrintWriter out = new PrintWriter(fos);
                            StreamResult streamResult = new StreamResult(out);
                            // PrintWriter from a Servlet
                            //PrintWriter out = response.getWriter();
                            //StreamResult streamResult = new StreamResult(out);
                            SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
                            // SAX2.0 ContentHandler.
                            TransformerHandler hd = tf.newTransformerHandler();
                            Transformer serializer = hd.getTransformer();
                            serializer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
                            serializer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,"users.dtd");
                            serializer.setOutputProperty(OutputKeys.INDENT,"yes");
                            hd.setResult(streamResult);
                            hd.startDocument();
                            AttributesImpl atts = new AttributesImpl();
                            // USERS tag.
                            hd.startElement("","","USERS",atts);
                            // USER tags.
                            String[] id = {"PWD122","MX787","A4Q45"};
                            String[] type = {"customer","manager","employee"};
                            String[] desc = {"Tim@Home","Jack&Moud","John D'oe"};
                            for (int i=0;i<id.length;i++){
                                    atts.clear();
                                    atts.addAttribute("","","ID","CDATA",id);
    atts.addAttribute("","","TYPE","CDATA",type[i]);
    hd.startElement("","","USER",atts);
    hd.characters(desc[i].toCharArray(),0,desc[i].length());
    hd.endElement("","","USER");
    hd.endElement("","","USERS");
    hd.endDocument();
    fos.close();
    }catch (IOException e){
    System.err.println ("Unable to write to file");
    System.exit(-1);
    }catch (TransformerConfigurationException tce){
    System.err.println("Error in: TransformerConfigurationException");
    }catch (SAXException spe) {
    // Error generated by the parser
    System.err.println("Error in: (SAXException");
    // Use the contained exception, if any
    Exception x = spe;
    if (spe.getException() != null)
    x = spe.getException();
    x.printStackTrace();
    -Hope this helps

  • What is the advent of writing xml mapping for servlet in tomcat4.1

    what is the adventage of writing xml mappings for servlet in tomcat4.1? why dont we write in tomcat 3.1?

    what is the adventage of writing xml mappings for
    servlet in tomcat4.1? why dont we write in tomcat 3.1?Tomcat 3.1 doesn't support it because it was not a common practice then. Tomcat 4.1 deployments were made J2EE compliant. Mapping in XML has an advantage of having a proper DTD for validation, which would be known to all. It serves as a common standard irrespective of the server you use.

  • Writing xml myself

    Can I try to write an xml file using just String stuff? Like this:
      public void savexmlfile() {
        File savedfile = FileChooserFrame.getFile();
        try {
          FileWriter writer = new FileWriter( savedfile+".xml" );
          String a = "\"a\"";
          writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
          writer.close();
        catch ( Exception ee ) {
          System.err.println( "Error writing XML file. (" + savedfile + "): " + ee.getMessage() );
      }I tried this and got this error in the xml file:
    The XML page cannot be displayed
    Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.
    System does not support the specified encoding. Error processing resource 'file:///C:/Documents and Settings/gwinal/mytest3.xml'. Line 1, Position 40
    <?xml version="1.0" encoding="UTF-8" ?>
    Is it possible to do it by hand or do I need to use an xml dom thingie? As you can see, I do not know xml very well. Thanks.
    Allyson

    Let me give a few pointers. JDOM is great for small files, easy to parse with. It sucks big time for larger files. It uses roughly 8x the memory of the file it works on. As does any DOM implementation. SAX/SAX2 parsers are a bit better. They parse somewhat faster and use very little memory during the parse. They are a pain and ugly to code though. Sure it can be done, just not my idea of fun.
    XMLPull on the other hand is a bit different. It is part of JSR 173 and will hopefully be standardized soon. Even so, the parsers are VERY fast, use less memory than the best SAX2 parser (picolo I think it is) and the parser itself is tiny! The "full blown" version is like 46K or something, while you can get by with a 9K version for simply reading XML.
    XMLPull DOES allow you to write output as well. What many don't realize is that XMLPull, even though they don't have a validator built in, unlike SAX/DOM they offer a very solid interface to plug one in, so it is easily possibly to add various xml validation implementations. That is part of why the parser is so small. Also, while it does parse XML 1.0 just fine, it may not parse EVERY piece of XML the way DOM/SAX does, in that it usually parses nodes, text, attributes/values, and white space, that is about it. For almost every need I have ever seen, this is all you really need to both parse/read xml and write it out. There are no doubt special situations where all the other possible elements could be useful, and in such a case XMLPull wouldn't work. There is a Serializer class with the full implementation of XMLPull and some examples that show you can easily add nodes with attribute/values and text and write it out to a stream (file, network, etc). It is still easier to use in my opinion other than JDOM. The JDOM API is very nice, but it is a memory hog the larger the xml file you need.
    What I suggest is you figure out if there is any potential for large files, like say 4 to 5MB and larger to ever be used in your app. If so, then I suggest you use SAX/SAX2, or give XMLPull a try. I think you'll find the speed, memory effeciency and easy coding of XMLPull far outweighs the use of SAX2, unless you absolutely have to validate an xml file against a dtd or schema. Then you should probably look at picolo, a very small/fast SAX2 parser.
    Good luck.

  • Choosing between SAX & DOM & StringBuffer class for writing XML

    Hii Javaties
    I need to create a XML document from a swing application.
    I need to store this xml in a file.
    For writing XML which parser should i use SAX or DOM or should i go for StringBuffer class.

    I'm not aware of a way to use SAX to create an XML document. It is used to view the contents of an existing XML document or data that is well-structured.
    That leaves you with a choice of DOM or StringBuffer. We cannot tell enought about what you are doing to know which is better. Each has some advantages and disadvantages.
    StringBuffer:
    + less overhead
    - no assistance in ensuring the validity of the result
    + greater control over layout of resulting document (how and when to indent)
    - any control over layout must be done by you.
    DOM (although this task is easier in JDOM)
    - more overhead
    - some learning curve
    + result is guaranteed to be valid XML.
    + there are pretty formatters to generate good looking results
    - there may be layout choices that the standard pretty formatters cannot do
    As an example, consider this part of the Document being created.
    You want <name>John Doe</name>
    With a StringBuffer, you can just add these pieces. With DOM, you need to:
    1) create an Element named "name".
    2) create a Text object with a value of "John Doe".
    3) add the Text object as a child of the Element
    4) add the Element to the parent
    Having done the DOM version (also a JDOM version) several times, I have developed an XMLHelper class that has several static methods to make simple, common constructs.
    It lets me do things like:
    parent.addChild( XmlHelper.makeElement( "name", customerName ) );
    So, the answer to your question is the same as many other questions: It depends.
    Dave Patterson

  • "PLS-00172: string literal too long" When Writing XML file into a Table

    Hi.
    I'm using DBMS_XMLStore to get a XML file into a db table. See the example below, I'm using that for my PL/SQL format. Problem is that because there're too many XML elements that I use in "xmldoc CLOB:= ...", I get "PLS-00172: string literal too long" error.
    Can someone suggest a workaround?
    THANKS!!!
    DECLARE
    insCtx DBMS_XMLStore.ctxType;
    rows NUMBER;
    xmldoc CLOB :=
    '<ROWSET>
    <ROW num="1">
    <EMPNO>7369</EMPNO>
    <SAL>1800</SAL>
    <HIREDATE>27-AUG-1996</HIREDATE>
    </ROW>
    <ROW>
    <EMPNO>2290</EMPNO>
    <SAL>2000</SAL>
    <HIREDATE>31-DEC-1992</HIREDATE>
    </ROW>
    </ROWSET>';
    BEGIN
    insCtx := DBMS_XMLStore.newContext('scott.emp'); -- get saved context
    DBMS_XMLStore.clearUpdateColumnList(insCtx); -- clear the update settings
    -- set the columns to be updated as a list of values
    DBMS_XMLStore.setUpdateColumn(insCtx,'EMPNO');
    DBMS_XMLStore.setUpdateColumn(insCtx,'SAL');
    DBMS_XMLStore.setUpdatecolumn(insCtx,'HIREDATE');
    -- Now insert the doc.
    -- This will only insert into EMPNO, SAL and HIREDATE columns
    rows := DBMS_XMLStore.insertXML(insCtx, xmlDoc);
    -- Close the context
    DBMS_XMLStore.closeContext(insCtx);
    END;
    /

    You ask where am getting the XML doc. Well, am not
    getting the doc itself.I either don't understand or I disagree. In your sample code, you're certainly creating an XML document-- your local variable "xmldoc" is an XML document.
    DBMS_XMLSTORE package needs
    to know the canonical format and that's what I
    hardcoded. Again, I either don't understand or I disagree... DBMS_XMLStore more or less assumes the format of the XML document itself-- there's a ROWSET tag, a ROW tag, and a then whatever column tags you'd like. You can override what tag identifies a row, but the rest is pretty much assumed. Your calls to setUpdateColumn identifies what subset of column tags in the XML document you're interested in.
    Later in code I use
    DBMS_XMLStore.setUpdateColumn to specify which
    columns are to be inserted.Agreed.
    xmldoc CLOB :=
    '<ROWSET>
    <ROW num="1">
    <KEY_OLD> Smoker </KEY_OLD>
    <KEY_NEW> 3 </KEY_NEW>
    <TRANSFORM> Specified </TRANSFORM>
    <KEY_OLD> Smoker </KEY_OLD>
    <VALUEOLD> -1 </VALUEOLD>
    EW> -1 </VALUENEW>
         <DESCRIPTION> NA </DESCRIPTION>
    </ROW>
    ROWSET>';This is your XML document. You almost certainly want to be reading this from the file system and/or have it passed in from another procedure. If you hard-code the XML document, you're limited to a 32k string literal, which is almost certainly causing the error you were reporting initially.
    As am writing this I'm realizing that I'm doing this
    wrong, because I do need to read the XML file from
    the filesystem (but insert the columns
    selectively)...What I need to come up with is a proc
    that would grab the XML file and do inserts into a
    relational table. The XML file will change in the
    future and that means that all my 'canonical format'
    code will be broken. How do I deal with anticipated
    change? Do I need to define/create an XML schema in
    10g if am just inserting into one relat. table from
    one XML file?What does "The XML file will change in the future" mean? Are you saying that the structure of the XML document will change? Or that the data in the XML document would change? Your code should only need to change if the structure of the document changes, which should be exceptionally uncommon and would only be an issue if you're adding another column that you want to work with, which would necessitate code changes.
    I found an article where the issue of changing XML
    file is dealt by using a XSL file (that's where I'd
    define the 'canonical format'), but am having a
    problem with creating one, because the source XML is
    screwed up in terms of the format:
    it's not <x> blah </x>
    <x2> blah </x2>
    x2="blah" x3="blah> ...etc
    Can you point me in the right direction, please?You can certainly use something like the DBMS_XSLProcessor package to transform whatever XML document you have into an XML document in an appropriate format for the XMLStore package and pass that transformed XML document into something like your sample procedure rather than defining the xmldoc local variable with a hard-coded document. Of course, you'd need to write appropriate XSL code to do the actual transform.
    Justin

  • Writing XML Object to a File

    Hi, I am using InDesign JavaScript to make an XML object in memory. When my script is done, I want to write the XML to a file. When I run the code below, the file is created, but the XML is not written to the file. Any help would be appreciated. Thanks. Rick
    #target indesign
    var partsMap = <partsMap />;
    savePartsMap (partsMap);
    function savePartsMap (partsMap) {
        var partsFile;
        // Make a File object for the parts map XML file.
        partsFile = new File("E:\\Test.xml");
        // Open the map file.
        partsFile.open("w");
        partsFile.write(partsMap);
        partsFile.close();

    Add partsFile.encoding = 'UTF-8'; right after your File instantiation.
    I'm not sure but you also might want to write partsMap.toXMLString() instead of the partsMap.toString() you're implicitly writing.
    Jeff

  • Error Writing Xml Table to the application server

    Hi All ,
    I am converting a internal table into a XML table using Fm SAP_CONVERT_TO_XML_FORMAT, And then writing it to the application server ,
    at the end of the file which is written to application server  there are some junk characters .
    when i download the same xml table to PC using gui_download there is no problem atr all .
    Its only when i using
    TRANSFER ls_XMLTAB-data TO lv_filename.  i get junk characters at the end and the error on the xml page is
    " An invalid character was found in text content. Error processing resource 'file:///C:/Documents and Settings..."
    This i guess is due to the line break ,
    Any help on resolving would be great thanks
    Regards
    Vinay Kolla

    I would simply suggest to convert xml xstring to binary table, then transfer the file in binary mode. This way you avoid character conversions which might lead to inconsistencies. So you need the following
    CALL TRANSFORMATION ...
        DATA ex_tab TYPE TABLE OF x255.
        CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
          EXPORTING
            buffer     = ostream_xml
          TABLES
            binary_tab = ex_tab.
    OPEN DATASET dset FOR OUTPUT IN BINARY MODE.
    "now transfer ex_tab to dset
    Regards
    Marcin

  • Writing XML without doing text processing

    Hello,
    In all examples I have when XML is written to a file the formatting is done my hand; That is, you have something like:
    System.out.print("<Tag attr= " + val + "/>");
    In .NET, on the other hand, you can just save a DOM XML Document with one line of code, something like:
    doc.write("myxml.xml");
    How do I save a DOM Document in Java without having to put in tags, attributes, quotes and all the other syntax by hand?
    Thank you,
    --Sergey                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Thank you for answering, DrClap,
    I'm sorry if I wasn't clear enough. My question was: I have a DOM and I want to save it into a file (or write to a stream in a more general case) as code-efficiently as possible. That includes not doing the formating (putting in tags, comments etc) by hand.
    The link you've given has a section on saving a DOM into a file but it seems to be much more complex than it needs to be. Their way of doing it involves transforms. Like I said, in .NET this would be a one-liner. Are you sure there is no faster way to do it in Java? I'd expect so because saving a DOM into a file looks like one of the most common tasks one might want to perform with XML...
    --Sergey                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Problem writing XML after opening dialog

    I'm using ScriptUI to create and update XML in a document (using Document.XMLElements methods).
    Before opening a Window with ScriptUI, I can read and write XML without problem.
    But after opening a Window containing some ScriptUI resources, I can only read the existing XML BUT NOT WRITE IT!
    My writing method is called from a button event :
    var myXMLRootNode = /* instanciated */
    myWindow.okButton = /* instanciated */
    myWindow.okButton.onClick = function() { myXMLRootNode.xmlElements.add(myTag, object) };
    myWindow.show();
    It looks like the onClick callback works OK for reading (I can recover all existing values without problem) but not for writing.
    Any idea ?

    Hey!
    Well, the thing is that you have to close dialog first before writing to document.
    myWindow.okButton.onClick = function(){myWindow.close(1);};
    var myWin = myWindow.show();
    if(myWin == true){
        myXMLRootNode.xmlElements.add(myTag, object);
    Hope it helps!
    tomaxxi
    http://indisnip.wordpress.com/

  • Writing XML without namespace?

    Hi,
    I have a "strange" xml schema in a system I need to export data to. It lacks any forms of namespace (possibly a converted DTD) and it seemd the FTP adapter (from BPEL) cant handle XML-types without namespaces.
    Is there a way to do this without using an opaque adapter and writing the data as "text"?
    The schema the file uses can be found here: http://services.agresso.com/schema/ABWSupplierCustomer/2004/07/02/ABWSupplierCustomer542.xsd
    // Michael Medin

    This works for both BPEL & ESB:
    1. Build an XSD for the source system adapter/process with no XSD.
    2. Build another XSD which acts like wrapper of original XSD.
    3. In the Wrapper XSD include the actual xsd.This one is sample xsd which has the piece of code
          <?xml version="1.0" encoding="windows-1252" ?>
           <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.org" targetNamespace="http://xmlns.oracle.com/BPELProcess2"
          xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" nxsd:version="DTD"
          elementFormDefault="qualified">
          <include schemaLocation="actual.xsd"/>
          </xsd:schema>The Target Namespace can be of any URL and this could be of anything.While polling the file or any JMS queue the adapter should include the wrapper xsd instead of actual xsd.This would read the file or any queue even if there is no namespace and the values can be transformed or assigned inside the process.
    Peace,
    G.

  • Preserving CDATA when reading then writing XML files

    Hi All,
    I have some source XML that needs to have an update applied and then written back out into a new directory. This all works fine except some of the other elements have values with CDATA around them in the input file and on the output file the CDATA is replaced and the characters substituted ie: turned in &amp;
    This is (I guess) default behaviour but I would like the CDATA preserved and writing out into the new XML file.
    How can I do this ?
    Regards,
    Steve

    Found the answer :
            DOMParser dp = new DOMParser();
            dp.retainCDATASection(true);
            dp.parse(xmlFile);
            xmlDoc = (XMLDocument)dp.getDocument();

  • Writing xml to more readable String

    Hi. I've written xml to string (without writing to a file) using the following method. Is there any way to make the xml string more readable? i.e have nice indentation, paragraphs etc like:
    <tag1>
        <tag2>
        </tag2>
    </tag1>
       public String getXMLData()
           String str = null;
           try
               ByteArrayOutputStream output= new ByteArrayOutputStream();
               TransformerFactory tfactory = TransformerFactory.newInstance();
               Transformer serializer = tfactory.newTransformer();
               serializer.setOutputProperty(
                   javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, dtdFile);
               serializer.transform(new DOMSource(document), new StreamResult(output));
               str = output.toString("UTF-8");
           catch(Exception e)
               e.printStackTrace();
           return str;
       }

    Hi,
    try
    serializer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT,"yes");
    regards

  • Error writing XML Table  on application server

    Hi All ,
    I am converting a internal table into a XML table using Fm SAP_CONVERT_TO_XML_FORMAT, And then writing it to the application server ,
    at the end of the file which is written to application server  there are some junk characters .
    when i download the same xml table to PC using gui_download there is no problem atr all .
    Its only when i using
    TRANSFER ls_XMLTAB-data TO lv_filename.  i get junk characters at the end and the error on the xml page is
    " An invalid character was found in text content. Error processing resource 'file:///C:/Documents and Settings..."
    This i guess is due to the line break ,
    Any help on resolving would be great thanks
    Regards
    Vinay Kolla

    1) Are you asking me to create a folder on Database directory which points to a folder on the Apps server ?I suggest creating an Oracle directory object (a database object) pointing to a real location (folder) on Application server.
    we DONOT want a hand shake between the DB Server and the APPS server.I don't see where the problem is.
    I'm not familiar with Apps R12 but there's no doubt the two servers are already communicating, at least App server should be able to access the DB for the whole thing to run.
    As I said :
    One way or another, the data has to make its way to the database, there's no workaround to that.How do you imagine the data will end up in a database table if it doesn't come to the DB server?
    There's no magical method out there, both servers have to communicate at some point.
    About client-server approaches (client being here the App server), you can read about accessing the XML DB repository in the XML DB Developer's Guide : http://download.oracle.com/docs/cd/E11882_01/appdev.112/e23094/toc.htm
    Other option : SQL*Loader can load a CLOB, or an XMLType column too
    Edited by: odie_63 on 19 déc. 2011 20:22

Maybe you are looking for

  • Production Orders, Varience  & costing

    I have many customer that are using SAP production orders with either moving average of FIFO and are surprised by the varience that are created by SAP production orders.  This is not typical of a 'actual' costing system. When a production order is cl

  • Counterstrike Source Issue in Mountain Lion?

    I had Mountain Lion since the release day but I never gamed that much before. I bought CS:S and used it back in Lion and it worked great on all Lion versions (10.7 - 10.7.4) Now I have ML I'm not able to launch CS:S anymore. I tried restarting Steam

  • Bulk 2.0 Get /Activity/Fields/{id} giving message endpoint not found

    In Bulk API 2.0 , we have  "GET /activities/fields/{id} ". Has anyone worked on this or has any idea as what "id " value would be? How can we get value for "id"? Can anyone give information on how activity object would be used in Bulk 2.0 because whe

  • SOA-Manufacturing Industries

    How SAO can help to increse its ROI(Returns on Investment) for a manufacturing industry? Edited by: RAJEEV SHARMA on Jan 28, 2009 5:39 AM

  • Firefighter Log File Archiving - Leading Practice

    Hi All, I am wondering if there is any leading practice by SAP or other on how often to archive data from Firefighter Logs. How big do these get? I know it depends on how much FF IDs get used, but is this a weekly, monthly, yearly type activity? Than