XML   Magic упрощаем сериализацию E-mail: khotin@gmx.com Игорь Хотинь
Background 11+ лет в IT-индустрии
6+ лет с Java
Сторонник гибкого дизайна Agile-практик
Source of the problem Ингридиенты для шаманства
public   class  CodeSource { List<CustomError>  errorList =  new  ArrayList<CustomError>(); public  CodeSource() { // fill the error list CustomError error =  new  CustomError(); error.setCode(101); error.setMessage( &quot;Is there an error in this code?&quot; ); errorList .add(error); // create the source Source source =  new  Source(); source.setProblem(101); // raise an error source.error( errorList ); } }
public   class  CustomError { private   int   code ; private  String  message ; public  String toString() { return   &quot;Error #&quot;  +  code  +  &quot;: &quot;  +  message ; } public   int  getCode() { return   this . code ; } public   void  setCode( int  code) { this . code  = code; } public   void  setMessage(String message) { this . message  = message; } }
public   class  Source { private   int   problem ; public   void  setProblem( int  problem) { this . problem  = problem; } public   void  error(List<CustomError> errorList) { for  (CustomError e: errorList) { if  (e.getCode() ==  this . problem ) { System. err .println(e); return ; } } System. err .println( &quot;Error: error not found&quot; ); } }
Source of the problem Константы в коде
Data-driven approach
XML
Почему XML? Стандарт
Доступные средства парсинга и верификации
Self-describing (в определённой степени)
Human-readable (в определённой степени)
Сложный, многословный, перегруженный
Алтернатива: JSON, YAML, SDL...
XML в нашей индустрии: всерьёз и надолго
< config > < handler >   < error >   < code > 101 </ code >   < message > Not our fault </ message >   </ error >   < error >   < code > 102 </ code >   < message > Keyboard not found... press F1 to continue </ message >   </ error >     < error >   < code > 103 </ code >   < message > Reserved for future mistakes by our developers </ message >   </ error > </ handler > < source > < problem > 102 </ problem > </ source > </ config >
XML Binding XML -> Java Beans -> XML
Лёгкий для понимания
Минимум кода, быстрая реализация
Гибкий
SAX - Simple API for XML Event-driven parsing
Максимум скорости
Минимум памяти
Сложность в обработке сложных структур
Read-only
List<CustomError>  errorList  =  new  ArrayList<CustomError>(); Source  source  =  new  Source(); public  SaxSource(InputStream input) { try  { SAXParserFactory factory = SAXParserFactory. newInstance (); SAXParser saxParser = factory.newSAXParser(); saxParser.parse(input,  this ); source .error( errorList ); }  catch  (Throwable e) { e.printStackTrace(); } }
String  tempVal ; CustomError  tempError ; public   void  startElement(String uri, String localName, String qName, Attributes attributes)  throws  SAXException { tempVal  =  &quot;&quot; ; if  (qName.equalsIgnoreCase( &quot;error&quot; )) { tempError  =  new  CustomError(); } } public   void  characters( char [] ch,  int  start,  int  length) throws  SAXException { tempVal  +=  new  String(ch, start, length); } public   void  endElement(String uri, String localName, String qName) throws  SAXException { if  (qName.equalsIgnoreCase( &quot;error&quot; )) { errorList .add( tempError ); }  else   if  (qName.equalsIgnoreCase( &quot;message&quot; )) { tempError .setMessage( tempVal ); }  else   if  (qName.equalsIgnoreCase( &quot;code&quot; )) { tempError .setCode(Integer. parseInt ( tempVal .trim())); }  else   if  (qName.equalsIgnoreCase( &quot;problem&quot; )) { source .setProblem(Integer. parseInt ( tempVal .trim())); } }
DOM – Document Object Model Универсальная модель
XML-дерево
Ресурсоёмко
Boilerplate-код
No Java-feel
List<CustomError>  errorList  =  new  ArrayList<CustomError>(); Source  source  =  new  Source(); public  DomSource(InputStream input) { try  { DocumentBuilderFactory dbf = DocumentBuilderFactory. newInstance (); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(input); Element root = doc.getDocumentElement(); NodeList nl = root.getElementsByTagName( &quot;handler&quot; ); if (nl !=  null  && nl.getLength() > 0) { Element e = (Element)nl.item(0); NodeList errList = e.getElementsByTagName( &quot;error&quot; ); for ( int  i = 0; i < errList.getLength(); i++) { CustomError error =  new  CustomError(); Element el = (Element)errList.item(i); if  (el ==  null )  continue ; NodeList clist = el.getElementsByTagName( &quot;code&quot; ); if  (clist !=  null  && clist.getLength() > 0) { error.setCode(Integer. parseInt ( clist.item(0).getTextContent())); } NodeList mlist = el.getElementsByTagName( &quot;message&quot; ); if  (mlist !=  null  && mlist.getLength() > 0) { error.setMessage(mlist.item(0).getTextContent()); } this . errorList .add(error); } } дурDOM
nl = root.getElementsByTagName( &quot;source&quot; ); if  (nl !=  null  && nl.getLength() > 0) { Element src = (Element)nl.item(0); NodeList plist = src.getElementsByTagName( &quot;problem&quot; ); if  (plist !=  null  && plist.getLength() > 0) { this . source .setProblem(Integer. parseInt (plist.item(0) .getTextContent())); } } XMLSerializer serializer =  new  XMLSerializer();   serializer.setOutputCharStream( new  java.io.FileWriter( &quot;out.xml&quot; ));   serializer.serialize(doc); }  catch (Exception e) { e.printStackTrace(); } source .error( errorList ); }
DOM + Xpath Гибкая выборка нужных данных
Ресурсоёмко

XML Magic

  • 1.
    XML Magic упрощаем сериализацию E-mail: khotin@gmx.com Игорь Хотинь
  • 2.
    Background 11+ летв IT-индустрии
  • 3.
  • 4.
  • 5.
    Source of theproblem Ингридиенты для шаманства
  • 6.
    public class CodeSource { List<CustomError> errorList = new ArrayList<CustomError>(); public CodeSource() { // fill the error list CustomError error = new CustomError(); error.setCode(101); error.setMessage( &quot;Is there an error in this code?&quot; ); errorList .add(error); // create the source Source source = new Source(); source.setProblem(101); // raise an error source.error( errorList ); } }
  • 7.
    public class CustomError { private int code ; private String message ; public String toString() { return &quot;Error #&quot; + code + &quot;: &quot; + message ; } public int getCode() { return this . code ; } public void setCode( int code) { this . code = code; } public void setMessage(String message) { this . message = message; } }
  • 8.
    public class Source { private int problem ; public void setProblem( int problem) { this . problem = problem; } public void error(List<CustomError> errorList) { for (CustomError e: errorList) { if (e.getCode() == this . problem ) { System. err .println(e); return ; } } System. err .println( &quot;Error: error not found&quot; ); } }
  • 9.
    Source of theproblem Константы в коде
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
    XML в нашейиндустрии: всерьёз и надолго
  • 19.
    < config >< handler > < error > < code > 101 </ code > < message > Not our fault </ message > </ error > < error > < code > 102 </ code > < message > Keyboard not found... press F1 to continue </ message > </ error > < error > < code > 103 </ code > < message > Reserved for future mistakes by our developers </ message > </ error > </ handler > < source > < problem > 102 </ problem > </ source > </ config >
  • 20.
    XML Binding XML-> Java Beans -> XML
  • 21.
  • 22.
  • 23.
  • 24.
    SAX - SimpleAPI for XML Event-driven parsing
  • 25.
  • 26.
  • 27.
    Сложность в обработкесложных структур
  • 28.
  • 29.
    List<CustomError> errorList = new ArrayList<CustomError>(); Source source = new Source(); public SaxSource(InputStream input) { try { SAXParserFactory factory = SAXParserFactory. newInstance (); SAXParser saxParser = factory.newSAXParser(); saxParser.parse(input, this ); source .error( errorList ); } catch (Throwable e) { e.printStackTrace(); } }
  • 30.
    String tempVal; CustomError tempError ; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { tempVal = &quot;&quot; ; if (qName.equalsIgnoreCase( &quot;error&quot; )) { tempError = new CustomError(); } } public void characters( char [] ch, int start, int length) throws SAXException { tempVal += new String(ch, start, length); } public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase( &quot;error&quot; )) { errorList .add( tempError ); } else if (qName.equalsIgnoreCase( &quot;message&quot; )) { tempError .setMessage( tempVal ); } else if (qName.equalsIgnoreCase( &quot;code&quot; )) { tempError .setCode(Integer. parseInt ( tempVal .trim())); } else if (qName.equalsIgnoreCase( &quot;problem&quot; )) { source .setProblem(Integer. parseInt ( tempVal .trim())); } }
  • 31.
    DOM – DocumentObject Model Универсальная модель
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
    List<CustomError> errorList = new ArrayList<CustomError>(); Source source = new Source(); public DomSource(InputStream input) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory. newInstance (); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(input); Element root = doc.getDocumentElement(); NodeList nl = root.getElementsByTagName( &quot;handler&quot; ); if (nl != null && nl.getLength() > 0) { Element e = (Element)nl.item(0); NodeList errList = e.getElementsByTagName( &quot;error&quot; ); for ( int i = 0; i < errList.getLength(); i++) { CustomError error = new CustomError(); Element el = (Element)errList.item(i); if (el == null ) continue ; NodeList clist = el.getElementsByTagName( &quot;code&quot; ); if (clist != null && clist.getLength() > 0) { error.setCode(Integer. parseInt ( clist.item(0).getTextContent())); } NodeList mlist = el.getElementsByTagName( &quot;message&quot; ); if (mlist != null && mlist.getLength() > 0) { error.setMessage(mlist.item(0).getTextContent()); } this . errorList .add(error); } } дурDOM
  • 37.
    nl = root.getElementsByTagName(&quot;source&quot; ); if (nl != null && nl.getLength() > 0) { Element src = (Element)nl.item(0); NodeList plist = src.getElementsByTagName( &quot;problem&quot; ); if (plist != null && plist.getLength() > 0) { this . source .setProblem(Integer. parseInt (plist.item(0) .getTextContent())); } } XMLSerializer serializer = new XMLSerializer(); serializer.setOutputCharStream( new java.io.FileWriter( &quot;out.xml&quot; )); serializer.serialize(doc); } catch (Exception e) { e.printStackTrace(); } source .error( errorList ); }
  • 38.
    DOM + XpathГибкая выборка нужных данных
  • 39.