0

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user1885868
  • 1,063
  • 3
  • 17
  • 31
  • 1
    I would look into JAXB, it makes parsing files into Java objects much easier. Take a look at [this other question](http://stackoverflow.com/q/14986221/2071828). – Boris the Spider Jan 24 '15 at 14:03
  • @BoristheSpider Is it faster than SAX? Because I have quite much XML files to parse (something more than 65000 for a start and then it will be way more) – user1885868 Jan 24 '15 at 14:20
  • 1
    JAXB uses SAX (or StAX) under the hood, so it certainly shouldn't be much slower. It essentially maps XML onto Java classes - much as you are trying to do. It also adds validation, which is a nice-to-have. – Boris the Spider Jan 24 '15 at 14:46
  • It seems interesting! I'll look into it. Thanks for the adivce! – user1885868 Jan 24 '15 at 14:51

1 Answers1

1

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();
        }
   }

}
terjekid
  • 390
  • 1
  • 11