2015-01-24 3 views
0

У меня есть файл XML, как этот:Объединить две строки, возвращаемые SAX

<?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> 

Я попытался пример в учебнике mkyong в here и я могу получить данные отлично от него с помощью SAX, это дает мне:

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

Но я хочу, чтобы дать мне что-то вроде этого:

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

в других терминах, Я хотел бы получить некоторые дочерние узлы узла Author, а не все из них, поместить их в строковую переменную и отобразить их.

Это класс я использую для того, чтобы разобрать автор с модификацией я пытался сделать:

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

} 

С этой модификацией, он только дает мне значение ArticleTitle и она ничего не возвращает в отношении авторов полных имен.

У меня есть другой класс для разбора узла ArticleTitle, и оба они вызываются в основном классе.

Что я сделал не так? И как я могу это исправить?

+1

Я бы заглянул в JAXB, это значительно упростило парсинг файлов в объекты Java. Взгляните на [этот другой вопрос] (http://stackoverflow.com/q/14986221/2071828). –

+0

@BoristheSpider Это быстрее, чем SAX? Поскольку у меня довольно много XML-файлов для синтаксического анализа (что-то более 65000 для начала, а затем это будет больше) – user1885868

+1

JAXB использует SAX (или StAX) под капотом, так что, конечно, это не должно быть намного медленнее. Он по существу отображает XML на классы Java - так же, как вы пытаетесь сделать. Он также добавляет валидацию, которая является приятной. –

ответ

1

Переменная fullName перезаписывается каждый раз, когда вызывается метод characters. Я думаю, вы должны переместить эту переменную в обработчик: init с пустой строкой, когда автор запускает и выписывает, когда он заканчивается. Конкатенация должна работать так же, как и вы. Я не пробовал это, но что-то похожее должно работать:

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

} 
Смежные вопросы