how to solve parser error in my application? - java

I parsed my xml file successfully, but now I am getting null value. so what mistake I make in my coding I don't know. I want to display my string value in my screen. Now I am trying to display that string value in text view format, but I am getting null value......
my xml file:
<Mobiles>
<Mobile>
<Phone>Nokia 1108</Phone>
<Network>GSM 900/1800 MHz</Network>
<Size>106x46x20 mm</Size>
<Ringtones>mono</Ringtones>
<SMS>yes</SMS>
<MMS>no</MMS>
<Email>no</Email>
<InstantMessaging >no</InstantMessaging>
</Mobile>
<Mobile>
<Phone>Nokia 1109</Phone>
<Network>GSM 900/1800 MHz</Network>
<Size>106x46x20 mm</Size>
<Ringtones>mono</Ringtones>
<SMS>yes</SMS>
<MMS>no</MMS>
<Email>no</Email>
<InstantMessaging >no</InstantMessaging>
</Mobile>
<Mobile>
<Phone>Nokia 1110</Phone>
<Network>GSM 900/1800 MHz</Network>
<Size>106x46x20 mm</Size>
<Ringtones>mono</Ringtones>
<SMS>yes</SMS>
<MMS>no</MMS>
<Email>no</Email>
<InstantMessaging >no</InstantMessaging>
</Mobile>
<Mobile>
<Phone>Nokia 1111</Phone>
<Network>GSM 900/1800 MHz</Network>
<Size>106x46x20 mm</Size>
<Ringtones>mono</Ringtones>
<SMS>yes</SMS>
<MMS>no</MMS>
<Email>no</Email>
<InstantMessaging >no</InstantMessaging>
</Mobile>
</Mobiles>
output:

Just briefly glancing at your code I'd say that the issue is the state transitions on your in_Mobiles variable. It will always be true from the start of the document to the end.
In your characters(char[], int, int) method, the very first conditional branch will thus consume all characters:
if (this.in_Mobiles) {
myParsedExampleDataSet.setMobiles(new String(ch, start, length));
The same behavior repeats in the use of in_Mobile, which if you fix the first one, will be the next culprit.
Edit:
Well, overall your parser implementation is kind of wonky. Try something like this instead:
First off, your ParsedExampleDataSet is a bit off.
Turn it into a List of Mobile objects instead, like this:
public class ParsedExampleDataSet extends ArrayList<Mobile>{
}
Next, make a bean class named Mobile, like this:
class Mobile {
private String Phone;
private String Network;
private String Size;
private String Ringtones;
private boolean SMS;
private boolean MMS;
private boolean Email;
private boolean InstantMessaging;
public String getPhone() {
return Phone;
}
public void setPhone(String phone) {
Phone = phone;
}
public String getNetwork() {
return Network;
}
public void setNetwork(String network) {
Network = network;
}
public String getSize() {
return Size;
}
public void setSize(String size) {
Size = size;
}
public String getRingtones() {
return Ringtones;
}
public void setRingtones(String ringtones) {
Ringtones = ringtones;
}
public boolean isSMS() {
return SMS;
}
public void setSMS(boolean sMS) {
SMS = sMS;
}
public boolean isMMS() {
return MMS;
}
public void setMMS(boolean mMS) {
MMS = mMS;
}
public boolean isEmail() {
return Email;
}
public void setEmail(boolean email) {
Email = email;
}
public boolean isInstantMessaging() {
return InstantMessaging;
}
public void setInstantMessaging(boolean instantMessaging) {
InstantMessaging = instantMessaging;
}
}
Finally, your DefaultHandler subclass needs to be reworked. Something like this ought to work.
class ExampleHandler extends DefaultHandler {
private ParsedExampleDataSet Mobiles;
private Mobile CurrentMobile;
private StringBuilder Characters;
public ParsedExampleDataSet getParsedExampleDataSet() {
return Mobiles;
}
public void startDocument() throws SAXException {
Mobiles = new ParsedExampleDataSet();
}
public void startElement(String namespaceUri, String localName, String qName, Attributes atts)
throws SAXException {
String name = localName.equals("") ? qName : localName;
if ("Mobile".equals(name)) {
CurrentMobile = new Mobile();
}
// Empty accumulated characters
Characters = null;
}
public void characters(char[] ch, int offset, int length) throws SAXException {
if (Characters == null) {
Characters = new StringBuilder(length);
}
Characters.append(ch, offset, length);
}
public void endElement(String namespaceUri, String localName, String qName) throws SAXException {
String name = localName.equals("") ? qName : localName;
if ("Mobile".equals(name)) {
Mobiles.add(CurrentMobile);
CurrentMobile = null;
} else if (CurrentMobile != null && Characters != null){
String value = Characters.toString();
if ("Phone".equals(name)) {
CurrentMobile.setPhone(value);
} else if ("Network".equals(name)) {
CurrentMobile.setNetwork(value);
} else if ("Size".equals(name)) {
CurrentMobile.setSize(value);
} else if ("Ringtones".equals(name)) {
CurrentMobile.setRingtones(value);
} else {
boolean yes = "yes".equalsIgnoreCase(value.trim());
if ("SMS".equals(name)) {
CurrentMobile.setSMS(yes);
} else if ("MMS".equals(name)) {
CurrentMobile.setMMS(yes);
} else if ("Email".equals(name)) {
CurrentMobile.setEmail(yes);
} else if ("InstantMessaging".equals(name)) {
CurrentMobile.setInstantMessaging(yes);
}
}
}
}
}
And, just running it like this should produce a result:
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
ExampleHandler handler = new ExampleHandler();
InputSource is = new InputSource(/* your XML goes here as an inputstream or reader*/);
parser.parse(is, handler);
ParsedExampleDataSet mobiles = handler.getParsedExampleDataSet();
for (Mobile mobile : mobiles) {
System.out.println(mobile.getPhone());
}

why do you have true in endElement method?
if (localName.equals("Mobiles")) {
this.in_Mobiles = true;
this could leads to always override mobiles and not setting correct field.

Related

Implementing custom prefix remover token filter in lucene producing dirty tokens

i'm trying to implement a lucene filter to remove a prefix from a term in a query.
It seems that sometime after multiple queries, the filter has been reused so the char buffer is dirty.
Code below is simplified, prefix is an external parameter.
public static class PrefixFilter extends TokenFilter {
private final PackedTokenAttributeImpl termAtt = (PackedTokenAttributeImpl) addAttribute(CharTermAttribute.class);
public PrefixFilter(TokenStream in) {
super(in);
}
#Override
public final boolean incrementToken() throws IOException {
if (!input.incrementToken()) {
return false;
}
String value = new String(termAtt.buffer());
value = value.trim();
value = value.toLowerCase();
value = StringUtils.removeStart(value, "prefix_");
if (value.isBlank()) {
termAtt.setEmpty();
} else {
termAtt.copyBuffer(value.toCharArray(), 0, value.length());
termAtt.setLength(value.length());
}
return true;
}
}
So after 10 or twelve queries, the value "prefix_a" became "abcde".
So i'm trying to add termBuffer offset end value in this way:
termAtt.setEmpty();
termAtt.resizeBuffer(value.length());
termAtt.copyBuffer(value.toCharArray(), 0, value.length());
termAtt.setLength(value.length());
termAtt.setOffset(0, value.length());
But i don't know if it's correct. Can anyone help me?
Thanks.
See if this helps you,
/**
* Standard number token filter.
*/
public class StandardnumberTokenFilter extends TokenFilter {
private final LinkedList<PackedTokenAttributeImpl> tokens;
private final StandardnumberService service;
private final Settings settings;
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
private final PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class);
private State current;
protected StandardnumberTokenFilter(TokenStream input, StandardnumberService service, Settings settings) {
super(input);
this.tokens = new LinkedList<>();
this.service = service;
this.settings = settings;
}
#Override
public final boolean incrementToken() throws IOException {
if (!tokens.isEmpty()) {
if (current == null) {
throw new IllegalArgumentException("current is null");
}
PackedTokenAttributeImpl token = tokens.removeFirst();
restoreState(current);
termAtt.setEmpty().append(token);
posIncAtt.setPositionIncrement(0);
return true;
}
if (input.incrementToken()) {
detect();
if (!tokens.isEmpty()) {
current = captureState();
}
return true;
} else {
return false;
}
}
private void detect() throws CharacterCodingException {
CharSequence term = new String(termAtt.buffer(), 0, termAtt.length());
Collection<CharSequence> variants = service.lookup(settings, term);
for (CharSequence ch : variants) {
if (ch != null) {
PackedTokenAttributeImpl token = new PackedTokenAttributeImpl();
token.append(ch);
tokens.add(token);
}
}
}
#Override
public void reset() throws IOException {
super.reset();
tokens.clear();
current = null;
}
#Override
public boolean equals(Object object) {
return object instanceof StandardnumberTokenFilter &&
service.equals(((StandardnumberTokenFilter)object).service) &&
settings.equals(((StandardnumberTokenFilter)object).settings);
}
#Override
public int hashCode() {
return service.hashCode() ^ settings.hashCode();
}
}
https://github.com/jprante/elasticsearch-plugin-bundle/blob/f63690f877cc7f50360faffbac827622c9d404ef/src/main/java/org/xbib/elasticsearch/plugin/bundle/index/analysis/standardnumber/StandardnumberTokenFilter.java

What is a better way to add different strings to different arraylists in Android?

I am trying to parse an RSS feed. I have an RSSHandler for that.
public class RSSHandler extends DefaultHandler {
boolean item = false;
int DATA_VALUE = 0;
private static ArrayList<String> photoUrl = new ArrayList<>();
private static ArrayList<String> title = new ArrayList<>();
private static ArrayList<String> hits = new ArrayList<>();
private static StringBuffer rssResult = new StringBuffer();
public static StringBuffer getRssResult() {
return rssResult;
}
public void setRssResult(StringBuffer rssResult) {
this.rssResult = rssResult;
}
#Override
public void startElement (String uri, String localName, String qName,
Attributes attrs) throws SAXException {
DATA_VALUE = 0;
if (localName.equals("item")) {
item = true;
if (rssResult != null && rssResult.length() > 0) {
feed.add(getRssResult());
setRssResult(new StringBuffer("\n"));
}
}
if (item) {
if (localName.equals(Constants.RSS_TITLE)) {
DATA_VALUE = 1;
} else if (localName.equals(Constants.RSS_LINK)) {
} else if (localName.equals(Constants.RSS_DESCRIPTION)) {
} else if (localName.equals(Constants.RSS_PUB_DATE)) {
} else if (localName.equals(Constants.RSS_SOURCE)) {
} else if (localName.equals(Constants.RSS_PICTURE)) {
DATA_VALUE = 2;
} else if (localName.equals(Constants.RSS_HITS)) {
DATA_VALUE = 3;
} else if (localName.equals(Constants.RSS_NEWS_TITLE)) {
DATA_VALUE = 1;
} else if (localName.equals(Constants.RSS_NEWS)) {
}
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
}
public void characters(char[] ch, int start, int length) throws SAXException {
String cdata = new String(ch, start, length);
if (DATA == 1) {
title.add(cdata.trim())
} else if (DATA == 2) {
photoUrl.add(cdata.trim())
} else if (DATA == 3) {
hits.add(cdata.trim())
}
}
}
How could I avoid using so many if-else in both the functions – startElement() and characters(). I was thinking of using a temporary array list and mapping it to the required Arraylist – (photoUrl, title or hits), something like using pointers in C.
Could I avoid using so many Arraylists for different kind of strings for my task?

How to get enum description in mybatis when serializing to JSON String

Question is how to get enum description in mybatis when serializing to JSON String
mybatis works fine to get an enum property and it also works fine to get description value by Model.DocFlowEnum.getStateName()
But how to get the description value this is a draft instead of ordinary value Draft when serializing to JSON String?
Because it is a list, I don’t want to loop to manually set the descrition value
DocFlowEnum, DocFlowEnumTypeHandler ,Model
Here is the enum with description
public enum DocFlowEnum{
Draft(0, "this is a draft"),
ToProcess(1, "this is to process"),
InProcess(2, "this is in process"),
private static final Map<Integer, DocFlowEnum> byState = new HashMap<>();
static {
for (DocFlowEnum e : DocFlowEnum.values()) {
if (byState.put(e.getState(), e) != null) {
throw new IllegalArgumentException("duplicate state: " + e.getState());
}
}
}
public static DocFlowEnum getByState(Integer state) {
return byState.get(state);
}
// original code follows
private final String stateName;
private final Integer state;
DocFlowEnum(Integer state, String stateName) {
this.state = state;
this.stateName = stateName;
}
public Integer getState() {
return state;
}
public String getStateName() {
return stateName;
}
}
here is the TypeHandler for mybatis
#MappedJdbcTypes(JdbcType.INTEGER)
#MappedTypes(value = DocFlowEnum.class)
public class DocFlowEnumTypeHandler extends BaseTypeHandler<DocFlowEnum> {
#Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, DocFlowEnum userStateEnum, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i,userStateEnum.getState());
}
#Override
public DocFlowEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {
int code =resultSet.getInt(s);
if(code>=0&&code<=5){
return DocFlowEnum.getByState(code);
}
return null;
}
#Override
public DocFlowEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {
int code = resultSet.getInt(i);
if(code>=0&&code<=5){
return DocFlowEnum.getByState(code);
}
return null;
}
#Override
public DocFlowEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
int code = callableStatement.getInt(i);
if(code>=0&&code<=5){
return DocFlowEnum.getByState(code);
}
return null;
}
}
Here is the Model
#Data
public class Document{
private DocFlowEnum stateEnum;
}
Thank you so much to everyone who helped.
OK, after 30minutes, I find the solution. so easy.
#JsonValue
public String getStateName() {
return stateName;
}
Maybe this can help others.

How to highlight words in TextView based on data

I want to highlight the text in the TextView that matches the data taken from the database. I use the code below but the text in the TextView doesn't change color.
Here's my code, but the setters and getters looks useless.
class getICT {
#SerializedName("eng")
private String eng;
#SerializedName("bhs")
private String bhs;
#SerializedName("kor")
private String kor;
public getICT(String eng, String bhs, String kor, String imageURL){
this.eng = eng;
this.bhs = bhs;
this.kor = kor;
}
/*
GETTERS N SETTERS
*/
public String getEng() {
return eng;
}
public String getBhs() {
return bhs;
}
public String getKor() {
return kor;
}
#Override
public String toString() {
return eng;
}
}
This is my interface, get from database
interface MyAPIService {
#GET("/ICT03/danger.php")
Call<getICT[]> getICT();
}
I write the code for highlight the text from here
ShowDetected.MyAPIService myAPIService = ShowDetected.RetrofitClientInstance.getRetrofitInstance().create(ShowDetected.MyAPIService.class);
Call<getICT[]> call = myAPIService.getICT();
call.enqueue(new Callback<getICT[]>() {
#Override
public void onResponse(Call<getICT[]> call, Response<getICT[]> response) {
getICT[] icts = response.body();
String s = showInput.getText().toString();
for(int i = 0; i < icts.length; i++) {
if (icts[i].equals(s)) {
showInput.setText(s);
showInput.setTextColor(Color.RED);
} else {
showInput.setTextColor(Color.BLACK);
}
}
}
#Override
public void onFailure(Call<getICT[]> call, Throwable t) {
Toast.makeText(ShowDetected.this, ""+t.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
});
Your code is incorrect, try this
boolean isHighlight = false
for(int i = 0; i < icts.length; i++) {
if (icts[i].equals(s)) {
isHighlight = true;
break;
}
}
showInput.setTextColor(isHighlight ? Color.RED : Color.BLACK);

Feeding a list of signals into wires

I'm given private List<Wire> inputs and a method public void feed(List<Signal> inSigs). I have to change signals (initialy each signal is ==Signal.X) in the List<Wire> inputs with the inSigs given in the parameter of the method feed(). THat's all I've been having trouble with. How could I change the state of List inputs with passed inSigs (notice: the parameter is of type <Signal>)? I've done smth but constantly getting and underline error under setSignal(x). I'm attached two classes (Gate and Wire below)
import java.util.*;
public abstract class Gate implements Logic {
private List<Wire> inputs;
private Wire output;
private String name;
public Gate(String name, List<Wire> ins, Wire out)
{
this.name = name;
this.output = out;
if(ins.size() == 0 || ins.isEmpty())
throw new ExceptionLogicParameters(false, 1, 0);
else
this.inputs = ins;
}
#Override
public void feed(List<Signal> inSigs)
{
for(Signal x: inSigs)
inputs.setSignal(x);
}
#Override
public void feed(String name)
{
((Wire) inputs).setName(name);
}
}
public class Wire {
private Signal signal;
private String name;
public Wire(String name)
{
this.name = name;
this.signal = Signal.X;
}
#Override
public String toString()
{
return "\""+ this.name+":"+this.signal+"\"";
}
#Override
public boolean equals(Object other)
{
if(other instanceof Wire)
{
Wire leftHandside = (Wire)other;
return this.name.equals(leftHandside.name) && this.signal == leftHandside.signal;
}
else
return false;
}
public Signal getSignal()
{
return this.signal;
}
public String getString()
{
return this.name;
}
public void setSignal(Signal signal)
{
this.signal = signal;
}
public void setName(String name)
{
this.name = name;
}
}
There is a bunch of ambiguity in the way your code and question reads.
I'll assume that the list of signals is the same size as your private list of wires, then:
public void feed(List<Signal> inSigs) {
// Needs precondition that inSigs.size() == input.size()
for (int i = 0; i < inSigs.size(); i++) {
inputs.get(i).setSignal(inSigs.get(i));
}
}
Otherwise you need a way to map your signals to wires, (probably by index).
Probably you need something like this then:
#Override
public void feed(List<Signal> inSigs)
{
if(inSigs.size() != inputs.size()) {
throw new ExceptionLogicParameters(false, 1, 0);
}
int i = 0;
for (Signal x: inSigs) {
inputs.get(i++).setSignal(x);
}
}

Categories

Resources