I want to parse and print XML tags using jdom2 (not w3c/xml.sax)
the root element is getting printed and the debug till before for loop is also there, but after that, there's blank, no syntax error, am I missing something in the for loop?
this is what my main looks like in the message reader class
public class XMLReaderDOM {
public static void main(String[] args) {
System.out.println("Starting out now");
try {
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File("file.xml");
Document doc = (Document) builder.build(xmlFile);
Element root = doc.getRootElement();
System.out.println("Document built");
List < Element > listGrpHdr = root.getChildren("GrpHdr");
List < GrpHdr > grphdrList = new ArrayList <>();
System.out.println("root element:" + doc.getRootElement().getName());
System.out.println("Right before for");
for (Element grphdrElement: listGrpHdr){
GrpHdr grphdr = new GrpHdr();
System.out.println("before getting our elements");
grphdr.setGrp_id(grphdrElement.getChildText("grp_id"));
grphdr.setCreationDateTime(grphdrElement.getChildText("creationDateTime"));
grphdr.setMessageType(grphdrElement.getChildText("messageType"));
grphdr.setGrp_hdr_xml(grphdrElement.getChildText("grp_hdr_xml"));
grphdrList.add(grphdr);
}
grphdrList.forEach(grphdr->{
System.out.println(grphdr.toString());
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Related
I need to add header to a STOMP message currently it is working as below but i am recreating the message , is it possible to just add native header without having to recreate the message for performance .
public class MyChannelInterceptor extends ChannelInterceptorAdapter {
#Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
StompCommand command = accessor.getCommand();
if(command != null) {
log.debug("Receiving msg {} from {}",command,accessor.getUser().getName());
if(command == StompCommand.SEND) {
log.debug("Adding expires header to msg {} from {}",command,accessor.getUser().getName());
String ttlString = accessor.getFirstNativeHeader("ttl");
long ttl = 30000;
try {
ttl = Long.parseLong(ttlString);
}
catch(Exception ex) {
log.error("TTL header received but not in correct format {}",ttlString);
}
accessor.addNativeHeader("expires", Long.toString(System.currentTimeMillis() + ttl));
return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
}
}
return message;
}
}
This is what i was looking for
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
The above code will get the actual StompHeaderAccessor of the message so if you manipulate the native headers they are directly reflected on the message while
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
will get a clone of the headers and you have to create a new message with the new cloned headers
full fixed code below
#Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
// StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if(accessor != null) {
StompCommand command = accessor.getCommand();
if(command != null) {
log.debug("Receiving msg {} from {}",command,accessor.getUser().getName());
if(command == StompCommand.SEND) {
log.debug("Adding expires header to msg {} from {}",command,accessor.getUser().getName());
String ttlString = accessor.getFirstNativeHeader("ttl");
long ttl = 30000;
if(ttlString != null) {
try {
ttl = Long.parseLong(ttlString);
}
catch(Exception ex) {
log.error("TTL header received but not in correct format {}",ttlString);
}
}
accessor.addNativeHeader("expires", Long.toString(System.currentTimeMillis() + ttl));
// I don't need any more to create a new message
//return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
}
}
}
return message;
}
Since addNativeHeader succeeds, that indicates the message is still mutable - see addNativeHeader().
In any case, since the NATIVE_HEADERS message header is a MultiValueMap-valued header, you can update the header contents in-place.
Hence, there is no need to create a new message.
You would have to create a new message if you add a new header to the message itself (rather than updating the mutable contents of an existing header).
EDIT
I just ran a test; as long as the message is still mutable, you can change it...
#Test
public void test() {
Map<String, Object> map = new HashMap<String, Object>();
MutableMessageHeaders headers = new MutableMessageHeaders(map);
Message<String> message = MessageBuilder.createMessage("foo", headers);
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
accessor.addNativeHeader("foo", "bar");
System.out.println(message.getHeaders().get(NativeMessageHeaderAccessor.NATIVE_HEADERS));
accessor.setImmutable();
try {
accessor.addNativeHeader("baz", "qux");
fail("expected IllegalStateException");
}
catch (IllegalStateException e) {
}
}
That said, are you experiencing a performance problem or is this just a perceived issue. Message creation is not expensive.
I am developing News app which shows over 50 News sites in webview and users can open links and read the news. I want to save some news as headlines or their links and show them in favourite page. and in favourite page can be clicked and deleted after reading it.
I worked on an thought with long press on page write link to a file and then read the file and make list of favorites. I tested with text view and writing file seems OK but reading it does not. my codes are:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myInflater= inflater.inflate(R.layout.fragment_main, container, false);
TextView txtView = (TextView) myInflater.findViewById(R.id.txtView);
txtView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(),
"You have pressed it long :)", Toast.LENGTH_LONG).show();
String filename ="favoritessss.txt";
File file = new File(getActivity().getFilesDir(), filename);
File directory = getActivity().getDir("SunShine", Context.MODE_WORLD_READABLE);
//String filename = "myfile";
String string = "Hello world000000000!"+"\r\n";
FileOutputStream outputStream;
try {
outputStream = getActivity().openFileOutput(filename, Context.MODE_WORLD_WRITEABLE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
});
//Find the view by its id
final TextView tv = (TextView)myInflater.findViewById(R.id.text_view);
txtView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Find the directory for the SD Card using the API
//Don't hardcode "/sdcard"
File sdcard = getActivity().getFilesDir();
//Get the text file
File file = new File(sdcard,"favoritessss.txt");
String[] text = new String[15];
try {
BufferedReader br = new BufferedReader(new FileReader(file));
for (int j=0; j>15; j++) text[j] = br.readLine();
br.close();
}
catch (IOException e) {
//You'll need to add proper error handling here
}
//Set the text
tv.setText(text[0]);
Toast.makeText(getActivity(), text[0],
Toast.LENGTH_SHORT).show();
}
});
return myInflater;
}
any comments?
In ANTLR, how to make output the tokens one by one following like push "enter" in keyboard that I try to a class named hello.java like this
public class Hello{
public static void main(String args[]){
System.out.println("Hello World ...");
}
}
Now, it is time to parse the tokens
final Antlr3JavaLexer lexer = new Antlr3JavaLexer();
try {
lexer.setCharStream(new ANTLRReaderStream(in)); // in is a file
} catch (IOException e) {
e.printStackTrace();
}
final CommonTokenStream tokens = new CommonTokenStream();
tokens.setTokenSource(lexer);
tokens.LT(10); // force load
Antlr3JavaParser parser = new Antlr3JavaParser(tokens);
System.out.println(tokens);
it gives me an output like this,
publicclassHello{publicstaticvoidmain(Stringarggs[]){System.out.println("Hello World ...");}}
How to make an output looked like this
public
class
Hello
{
public
static ... untill the end...
I've try using Stringbuilder, but it's not working.
Thanks 4 the help..
Instead of just printing out tokens, you have to iterate over tokenstream to get back desired result.
Modify your code like this.
final Antlr3JavaLexer lexer = new Antlr3JavaLexer();
try {
lexer.setCharStream(new ANTLRReaderStream(in)); // in is a file
} catch (IOException e) {
e.printStackTrace();
}
final CommonTokenStream tokens = new CommonTokenStream();
tokens.setTokenSource(lexer);
//tokens.LT(10); // force load - not needed
Antlr3JavaParser parser = new Antlr3JavaParser(tokens);
// Iterate over tokenstream
for (Object tk: tokens.getTokens())
{
CommonToken commontk = (CommonToken) tk;
if (commontk.getText() != null && commontk.getText().trim().isEmpty() == false)
{
System.out.println(commontk.getText());
}
}
After this, You will get this result.
public
class
Hello
{
public
static ... etc...
Hope this will solve your issue.
I am doing a project in Vaadin and need to do the following. I make a server request and get an XML string in response. And, I know nothing about how this XML file will look at run time. I need to convert this XML string into a vaadin tree.
I have seen some answers where they say to load into a HierarchicalContainer and all but I'm unable to make sense of it.
Please help me!
If you don't want to use HierarchicalContainer (I have no experience with that), you can just parse the XML document recursively like that: Recursive XML-parser
Then just add the items and set the parent. Something like this:
#Override
protected void init(VaadinRequest request) {
Tree tree = new Tree();
setContent(tree);
try {
File fXmlFile = new File("C:\\temp\\sample.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
Element root = doc.getDocumentElement();
Object rootItem = root.getNodeName();
tree.addItem(rootItem);
addChildrenToTree(tree, root.getChildNodes(), rootItem);
} catch (Exception e) { }
}
private void addChildrenToTree(Tree tree, NodeList children, Object parent) {
if (children.getLength() > 0) {
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
Object child = node.getNodeName();
tree.addItem(child);
tree.setParent(child, parent);
addChildrenToTree(tree, node.getChildNodes(), child);
}
}
}
I want to unmarshal an XML file to java object using JAXB. The XML file is very large and contains some nodes which I want to skip in some cases to improve performance as these elements are non editable by client java program.
A sample XML is as follows:
<Example id="10" date="1970-01-01" version="1.0">
<Properties>...</Properties>
<Summary>...</Summary>
<RawData>
<Document id="1">...</Document>
<Document id="2">...</Document>
<Document id="3">...</Document>
------
------
</RawData>
<Location></Location>
<Title></Title>
----- // more elements
</Example>
I have two use cases:
unmarshal into Example object which contains Properties, Summaries, RawData etc. without skipping any RawData. (already done this part)
unmarshal into Example object which exclude RawData. Elements nested in RawData is very large so do not want to read this in this use case.
Now I want to unmarshal the XML such that RawData can be skipped. I have tried the technique provided at this link.
Using technique provided in above link also skips all elements which come after RawData.
I have fixed the issue with XMLEventReader with following code:
public class PartialXmlEventReader implements XMLEventReader {
private final XMLEventReader reader;
private final QName qName;
private boolean skip = false;
public PartialXmlEventReader(final XMLEventReader reader, final QName element) {
this.reader = reader;
this.qName = element;
}
#Override
public String getElementText() throws XMLStreamException {
return reader.getElementText();
}
#Override
public Object getProperty(final String name) throws IllegalArgumentException {
return reader.getProperty(name);
}
#Override
public boolean hasNext() {
return reader.hasNext();
}
#Override
public XMLEvent nextEvent() throws XMLStreamException {
while (isEof(reader.peek())) {
reader.nextEvent();
}
return reader.nextEvent();
}
#Override
public XMLEvent nextTag() throws XMLStreamException {
return reader.nextTag();
}
#Override
public XMLEvent peek() throws XMLStreamException {
return reader.peek();
}
#Override
public Object next() {
return reader.next();
}
#Override
public void remove() {
reader.remove();
}
#Override
public void close() throws XMLStreamException {
reader.close();
}
private boolean isEof(final XMLEvent e) {
boolean returnValue = skip;
switch (e.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
final StartElement se = (StartElement) e;
if (se.getName().equals(qName)) {
skip = true;
returnValue = true;
}
break;
case XMLStreamConstants.END_ELEMENT:
final EndElement ee = (EndElement) e;
if (ee.getName().equals(qName)) {
skip = false;
}
break;
}
return returnValue;
}
}
While Unmarshalling just pass this eventReader to the unmarshal method
final JAXBContext context = JAXBContext.newInstance(classes);
final Unmarshaller um = context.createUnmarshaller();
Reader reader = null;
try {
reader = new BufferedReader(new FileReader(xmlFile));
final QName qName = new QName("RawData");
final XMLInputFactory xif = XMLInputFactory.newInstance();
final XMLEventReader xmlEventReader = xif.createXMLEventReader(reader);
final Example example =
(Example) um.unmarshal(new PartialXmlEventReader(xmlEventReader, qName));
}
} finally {
IOUtils.closeQuietly(reader);
}
I hope this would help
try {
// First create a new XMLInputFactory
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
// Setup a new eventReader
InputStream in = new FileInputStream("myXml");
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
// Read the XML document
Example example = null;
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
// If we have a example element we create a new example
if (startElement.getName().getLocalPart().equals("Example")) {
example = new Example();
// We read the attributes from this tag and add the date
// and id attribute to our object
Iterator<Attribute> attributes = startElement
.getAttributes();
while (attributes.hasNext()) {
Attribute attribute = attributes.next();
if (attribute.getName().toString().equals("date")) {
example.setDate(attribute.getValue());
} else if (attribute.getName().toString().equals("id")) {
example.setId(attribute.getValue());
}
}
}
//get the Properties tag and add to object example
if (event.isStartElement()) {
if (event.asStartElement().getName().getLocalPart()
.equals("Properties")) {
event = eventReader.nextEvent();
example.setProperites(event.asCharacters().getData());
continue;
}
}
//get the Summary tag and add to object example
if (event.asStartElement().getName().getLocalPart()
.equals("Summary")) {
event = eventReader.nextEvent();
example.setSummary(event.asCharacters().getData());
continue;
}
// when you encounter the Rawdata tag just continue
//without adding it to the object created
if (event.asStartElement().getName().getLocalPart()
.equals("Rawdata")) {
event = eventReader.nextEvent();
// don't do anything
continue;
}
//get the location tag and add to object example
if (event.asStartElement().getName().getLocalPart()
.equals("Location")) {
event = eventReader.nextEvent();
example.setLocation(event.asCharacters().getData());
continue;
}
// read and add other elements that can be added
}
// If we reach the end of an example element/tag i.e closing tag
if (event.isEndElement()) {
EndElement endElement = event.asEndElement();
if (endElement.getName().getLocalPart().equals("Example")) {
//do something
}
}
}
} catch (FileNotFoundException | XMLStreamException e) {
}