I am trying to make one application file format parser & generator. Application uses xml files with custom DTD. Currently I am thinking about writing object mapper with nokogiri to parse xml to objects and use these object to generate xml back. I have tried HappyMapper and xml-mapping but they didn't utilize full xml format. So Currently now I have made this but I think it is bit bad design.
http://pastie.org/5393012
You can use C# with XMLSerilaizer, it is the best. Here is the example:
---------------just a lot of entity ----------------------
using System;
namespace BuilderSerialization {
public class Address {
public Address() {}
public string Address1;
public string Address2;
public string City;
public string State;
public string Zip;
public string Country;
} }
using System;
namespace BuilderSerialization {
public class Author {
public Author() { }
public string FirstName;
public string MiddleName;
public string LastName;
public string Title;
public string Gender;
public Address AddressObject;
} }
namespace BuilderSerialization {
public class Book {
public Book() { }
public string Title;
public Author AuthorObject;
public string ISBN;
public double RetailPrice;
public string Publisher;
}}
-------------------------------------------------------
using System;
using System.Xml.Serialization;
using System.IO;
namespace BuilderSerialization {
class TestClass {
static void Main(string[] args) {
Book BookObject = new Book();
XmlSerializer ser = new XmlSerializer(typeof(Book));
TextWriter writer = new StreamWriter("booktest.xml");
BookObject.Title = "Practical LotusScript";
BookObject.ISBN = "1884777767 ";
BookObject.Publisher = "Manning Publications";
BookObject.RetailPrice = 43.95;
BookObject.AuthorObject = new Author();
BookObject.AuthorObject.FirstName = "Tony";
BookObject.AuthorObject.LastName = "Patton";
BookObject.AuthorObject.Gender = "Male";
BookObject.AuthorObject.AddressObject = new Address();
BookObject.AuthorObject.AddressObject.Address1 = "1 Main Street";
BookObject.AuthorObject.AddressObject.City = "Anywhere";
BookObject.AuthorObject.AddressObject.State = "KY";
BookObject.AuthorObject.AddressObject.Zip = "40000";
BookObject.AuthorObject.AddressObject.Country = "USA";
ser.Serialize(writer, BookObject);
writer.Close();
} } }
After that you get the XML:
<?xml version="1.0" encoding="utf-8"?>
<Book xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Title>Practical LotusScript</Title>
<AuthorObject>
<FirstName>Tony</FirstName>
<LastName>Patton</LastName>
<Gender>Male</Gender>
<AddressObject>
<Address1>1 Main Street</Address1>
<City>Anywhere</City>
<State>KY</State>
<Zip>40000</Zip>
<Country>USA</Country>
</AddressObject>
</AuthorObject>
<ISBN>1884777767 </ISBN>
<RetailPrice>43.95</RetailPrice>
<Publisher>Manning Publications</Publisher>
</Book>
Related
I have a #ConfigurationProperties-annotated #Configuration-class called LibraryConfig. It uses an inner class as a type definition for a property/configuration struture. When the class is an inner class instead of a standalone class I get "Elements [...] were left unbound" errors/exceptions. Why is this so and how can I fix it?
application.yml
initdata:
library:
name: awesome library
books:
- title: Book1
author: Author Abc
- title: Book2
author: Author Xyz
LibraryConfiguration.java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
#Configuration
#ConfigurationProperties(prefix = "initdata.library")
public class LibraryConfiguration {
private String name;
private List<Book> books;
// getters left out for simplicity of example
public void setName(String name) {
this.name = name;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public LibraryConfiguration() {
}
public static class Book {
private String title;
private String author;
public Book() {
}
// getters left out for simplicity of example
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
}
}
You either create a standalone class or you must declare inner classes as static class! Otherwise Spring doesn't see it just as a "type definition" but tries to create an instance of it - which of course doesn't work with the given yml-configuration. Change the code to the following
// ...
public LibraryConfiguration() {
}
// This class MUST be static, otherwise Spring will tell "Elements [...] were left unbound".
// If it's static, it's just a "type definition";
// otherwise spring tries to create an insance
public static class Book {
private String title;
private
// ...
Hi there im having some issues with MongoDb i have a CRUD and this is the code im using
First the POJO:
#Data
#Document(collection = "Informacion")
public class Informacion {
//Declaration code
public Informacion(Pais pais, Date fechaCreacion, String nombre, Boolean sexo,
Date fechaNacimiento, List<Preferencias> preferencias, String numTelefono, String usuario,
List<RedesSociales> redes, String contraseniaTW, String contraseniaFB, String contraseniaIG,
Grupo grupo, String paqChip, String email, String contraseniaMail, String fuente,
Date fechaRecarga) {
this.pais = pais;
this.fechaCreacion = fechaCreacion;
this.nombre = nombre;
this.sexo = sexo;
this.fechaNacimiento = fechaNacimiento;
this.preferencias = preferencias;
this.numTelefono = numTelefono;
this.usuario = usuario;
this.redes = redes;
this.contraseniaTW = contraseniaTW;
this.contraseniaFB = contraseniaFB;
this.contraseniaIG = contraseniaIG;
this.grupo = grupo;
this.paqChip = paqChip;
this.email = email;
this.contraseniaMail = contraseniaMail;
this.fuente = fuente;
this.fechaRecarga = fechaRecarga;
}
}
Now the DAO:
#Repository
public interface informacionRepo extends MongoRepository<Informacion,String> {
Informacion findByIdInformacion(String id);
}
And the controller:
#RestController
#RequestMapping("/Informacion")
public class InformacionControlador {
#Autowired
private informacionRepo informacioRepo;
public InformacionControlador(informacionRepo informacioRepo) {
this.informacioRepo = informacioRepo;
}
#GetMapping("/Listar")
public List<Informacion> getAll(){
List<Informacion> info = this.informacioRepo.findAll();
System.out.println(info.isEmpty());
return info;
}
#PutMapping
public void insert(#RequestBody Informacion informacion){
this.informacioRepo.insert(informacion);
}
public void update(#RequestBody Informacion informacion){
this.informacioRepo.save(informacion);
}
#DeleteMapping("/Listar/{id}")
public void delete(#PathVariable("id") String id){
this.informacioRepo.deleteById(id);
}
#GetMapping("/Listar/{id}")
public Informacion getById(#PathVariable("id") String id){
Informacion info = this.informacioRepo.findByIdInformacion(id);
return info;
}
}
Im using POSTMAN to test the methods above but im getting empty answers, the data is already set on the Database, im using a method call seeder that fills the data also y check it with robo mongo and the data is there but still getting empty answers also when i try the insert method i get 403 error.
Thanks for your help
This is the answer seen from the web browser
The problem was that im using the annotation #Data from lombok but i didnt enable annotation processing in the IDE just enable it and works :D
SampleMessage class:
#XmlRootElement(name = "SampleMessage")
#XmlAccessorType(XmlAccessType.FIELD)
public class SampleMessage {
#XmlAttribute
private String type;
#XmlElement(name = "Content", required = true)
private Content content;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
#XmlAccessorType(XmlAccessType.FIELD)
private static class Content {
#XmlValue
private String value;
#XmlAttribute(name = "name")
private String name;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
The Spring Boot - Rest Controller I have the follow method which basically just output the same XML form with what we passed, well supposed to be. This is just to check if it is parsing the XML properly.
#PostMapping(consumes = {MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_XML_VALUE})
public String handler(#RequestBody SampleMessage message) {
StringWriter writer = new StringWriter();
try {
JAXBContext jaxbContext = JAXBContext.newInstance(SampleMessage.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(message, writer);
} catch (JAXBException ex) {
System.out.println(ex.toString());
}
return writer.toString();
}
XML Sample 1: This is the initial XML sample I have:
<?xml version="1.0" encoding="UTF-8"?>
<SampleMessage type="TestType">
<Content name="TestContent">This is a sample content.</Content>
</SampleMessage>
Output (XML Sample 1): The output I get from the marshaller is this:
<?xml version="1.0" encoding="UTF-8"?>
<SampleMessage type="TestType">
<Content name="TestContent"/>
</SampleMessage>
Notice that there is no content text in the "Content" element that reads "This is a sample content". However, if I pass additional element Value inside "Content" element then it is able to output correctly.
XML Sample 2
<?xml version="1.0" encoding="UTF-8"?>
<SampleMessage type="TestType">
<Content name="TestContent"><Value>This is a sample content.</Value></Content>
</SampleMessage>
Correct Output
<?xml version="1.0" encoding="UTF-8"?>
<SampleMessage type="TestType">
<Content name="TestContent">This is a sample content.</Content>
</SampleMessage>
Any thoughts why is this?
This has resolved. Just noticed that this is a duplicate from my other post, sorry.
JAXB #XmlValue not able to get the text, Not generating empty XML element, and not able to read attribute
public class Something{
private string id;
private SomethingElse somethingElse;
private OtherProperties...
}
public class SomethingElse{
private string id;
private OtherProperties...
}
public class SomethingDto{
private string id;
private string somethingElseId;
private OtherProperties...
}
When mapping from something to SomethingDto I have to do
<mapping>
<class-a>Something</class-a>
<class-b>SomethingDto</class-b>
<field>
<a>somethingElse.id</a>
<b>somethingElse</b>
</field>
</mapping>
I'm not sure how to do the opposite what I want is "new SomethingElse" and then set the id like this
public class Something{
private string id;
private SomethingElse somethingElse;
private OtherProperties...
public void setSomethingElseById(String somethingElseId){
somethingElse = new SomethingElse;
somethingElse.setId(somethingElseId);
}
}
<mapping>
<class-a>SomethingDto</class-a>
<class-b>Something</class-b>
<field>
<a>somethingElse</a>
<b set-method='setSomethingElseById(SomethingElse)' >somethingElse</b>
</field>
</mapping>
This really looks like a bad solution so I tried the custom converter
public class SomethingDtoToSomethingConverter extends DozerConverter<String, SomethingElse> {
public SomethingDtoToSomethingConverter () {
super(String.class, SomethingElse.class);
}
#Override
public SomethingElse convertTo(String source, SomethingElse destination) {
destination = new SomethingElse();
destination.setId(source);
return destination;
}
#Override
public String convertFrom(SomethingElse source, String destination) {
destination = source.getId();
return destination ;
}
}
This looks like a ridiculous amount of code for something really simple
How can I achieve a cleaner solution?
What version of Dozer are you using? This should just work out of the box using the first mapping you defined as Dozer mappings are bi-directional by default.
I've created an example based on your code with a unit test which passes:
Something.java
public class Something {
private String id;
private SomethingElse somethingElse;
...
}
SomethingElse.java
public class SomethingElse {
private String id;
...
}
SomethingDto.java
public class SomethingDto {
private String id;
private String somethingElseId;
...
}
dozer.xml
<mapping>
<class-a>Something</class-a>
<class-b>SomethingDto</class-b>
<field>
<a>somethingElse.id</a>
<b>somethingElseId</b>
</field>
</mapping>
Unit Test
public class DozerMappingTest {
private DozerBeanMapper beanMapper;
#Test
public void sourceToDestination() {
List<String> mappingFiles = new ArrayList<String>();
mappingFiles.add("dozer.xml");
this.beanMapper = new DozerBeanMapper(mappingFiles);
Something source = new Something();
source.setId("A");
SomethingElse somethingElse = new SomethingElse();
somethingElse.setId("B");
source.setSomethingElse(somethingElse);
SomethingDto dest = beanMapper.map(source, SomethingDto.class);
assertEquals("A", dest.getId());
assertEquals("B", dest.getSomethingElseId());
}
#Test
public void destinationToSource() {
List<String> mappingFiles = new ArrayList<String>();
mappingFiles.add("dozer.xml");
this.beanMapper = new DozerBeanMapper(mappingFiles);
SomethingDto source = new SomethingDto();
source.setId("A");
source.setSomethingElseId("B");
Something dest = beanMapper.map(source, Something.class);
assertEquals("A", dest.getId());
assertEquals("B", dest.getSomethingElse().getId());
}
}
I have this enum :
public enum DocumentTypes {
PDF("PDF Document"), JPG("Image files (JPG)"), DOC("Microsoft Word documents");
private final String displayName;
DocumentTypes(final String display) {
this.displayName = display;
}
#Override
public String toString() {
return this.displayName;
}
}
And a model like this :
#Entity
#Table(name = "documents")
public class Document extends Model {
#Id
public Long id;
#Constraints.Required
#Formats.NonEmpty
#Enumerated(EnumType.STRING)
#Column(length=20, nullable=false)
public DocumentTypes type;
#Constraints.Required
#Formats.NonEmpty
#Column(nullable=false)
public String document;
}
I match the enum using this in my controller :
DynamicForm form = form().bindFromRequest();
// ...
Document doc = new Document();
doc.type = DocumentTypes.valueOf(form.field("type").value());
doc.save();
The problem is that in database, it's stored as "Microsoft Word documents", but I would prefer to store it as DOC.
How can I do that?
You can define it very fine granular with the Anotation EnumMapping or EnumValue. This works with the old version org.avaje.ebean.
It seems that there was a complete rewrite of the code. In the actual version there is a different approach.