Search code examples
javaxmlsaxsaxparser

Join two strings retrieved by SAX


I have an XML file like this one:

<?xml version="1.0" encoding="UTF-8"?>
<Article>
    <ArticleTitle>Java-SAX Tutorial</ArticleTitle>
    <Author>
        <FamilyName>Yong</FamilyName>
        <GivenName>Mook</GivenName>
        <GivenName>Kim</GivenName>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </Author>
    <Author>
        <FamilyName>Low</FamilyName>
        <GivenName>Yin</GivenName>
        <GivenName>Fong</GivenName>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </Author>
</Article>

I have tried the example in mkyong's tutorial here and I can retrieve data perfectly from it using SAX, it gives me:

Article Title : Java-SAX Tutorial
Given Name : Kim
Given Name : Mook
Family Name : Yong
Given Name : Yin
Given Name : Fong
Family Name : Low

But I want it to give me something like this:

Article Title : Java-SAX Tutorial
Author : Kim Mook Yong
Author : Yin Fong Low

In other terms, I would like to retrieve some of the child nodes of the node Author, not all of them, put them in a string variable and display them.

This is the class I use in order to parse the Authors with the modification I have tried to do:

public class ReadAuthors {

    public void parse(String filePath) {

        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {

                boolean bFamilyName = false;
                boolean bGivenName = false;

                @Override
                public void startElement(String uri, String localName,String qName,
                            Attributes attributes) throws SAXException {

                    if (qName.equalsIgnoreCase("FamilyName")) {
                        bFamilyName = true;
                    }

                    if (qName.equalsIgnoreCase("GivenName")) {
                        bGivenName = true;
                    }

            }

            @Override
            public void endElement(String uri, String localName,
                String qName) throws SAXException {

            }

            @Override
            public void characters(char ch[], int start, int length) throws SAXException {

                String fullName = "";

                String familyName = "";
                String givenName ="";

                if (bFamilyName) {
                    familyName = new String(ch, start, length);
                    fullName += familyName;
                    bFamilyName = false;
                }

                if (bGivenName) {
                    givenName = new String(ch, start, length);
                    fullName += " " + givenName;
                    bGivenName = false;
                }

                System.out.println("Full Name : " + fullName);

            }
             };

             saxParser.parse(filePath, handler);

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

}

With this modification, it only gives me the ArticleTitle value and it doesn't return anything regarding the authors full names.

I have another class for parsing the ArticleTitle node and they are both called in a Main class.

What did I do wrong? And how can I fix it?


Solution

  • The fullName variable is overwritten everytime when the characters method is called. I think you should move out that variable into the handler: init with empty string when Author starts and write out when it ends. The concatenation should work as you did. I haven't tried this out but something similear should work:

    public class ReadAuthors {
    
        public void parse(String filePath) {
    
            try {
    
                SAXParserFactory factory = SAXParserFactory.newInstance();
                SAXParser saxParser = factory.newSAXParser();
    
                DefaultHandler handler = new DefaultHandler() {
    
                    boolean bName = false;
                    String fullName = "";
    
                    @Override
                    public void startElement(String uri, String localName,String qName,
                                Attributes attributes) throws SAXException {
    
                        if (qName.equalsIgnoreCase("FamilyName")) {
                            bName = true;
                        }
    
                        if (qName.equalsIgnoreCase("GivenName")) {
                            bName = true;
                        }
    
                        if (qName.equalsIgnoreCase("Author")) {
                            fullName = "";
                        }
    
                }
    
                @Override
                public void endElement(String uri, String localName,
                    String qName) throws SAXException {
                        if (qName.equalsIgnoreCase("Author")) {
                            System.out.println("Full Name : " + fullName);
                        }
                }
    
                @Override
                public void characters(char ch[], int start, int length) throws SAXException {
    
                    String name = "";
    
                    if (bName) {
                        name = new String(ch, start, length);
                        fullName += name;
                        bName = false;
                    }
    
                }
                 };
    
                 saxParser.parse(filePath, handler);
    
            } catch (Exception e) {
                   e.printStackTrace();
            }
       }
    
    }