Java 字符串变量在传递到另一个对象时会失去其值
我正试图为学校项目构建一个简单的程序,将xml文件转换成对象,反之亦然。我试图将从标记之间获得的xml数据存储到一个对象中,然后将该对象存储到另一个类的另一个对象中。问题是,每次我试图将xml解析中的一些字符串传递给第一个存储对象(如名称、平台等)时,它们的值都会丢失。字符串确实被传递到存储对象,但存储只是从“XXXXXX”变为“”。我们的指挥官和我都无法解决这个问题。有什么想法吗 下面是造成混乱的类Java 字符串变量在传递到另一个对象时会失去其值,java,class,variables,Java,Class,Variables,我正试图为学校项目构建一个简单的程序,将xml文件转换成对象,反之亦然。我试图将从标记之间获得的xml数据存储到一个对象中,然后将该对象存储到另一个类的另一个对象中。问题是,每次我试图将xml解析中的一些字符串传递给第一个存储对象(如名称、平台等)时,它们的值都会丢失。字符串确实被传递到存储对象,但存储只是从“XXXXXX”变为“”。我们的指挥官和我都无法解决这个问题。有什么想法吗 下面是造成混乱的类 public class MySaxParser extends DefaultHandler
public class MySaxParser
extends DefaultHandler {
public static int element;
public static String elementit[] = {"name","studio","genre","platform","published"};
public static String Name, Studio, Genre, Platform, Published;
public static OutFile outF = new OutFile();
private static Library Pelit = new Library();
private static Game peli;
public Library getLib(){
return Pelit;
}
public void parse() {
/*if (args.length != 1) {
System.out.println("Usage: java .MySaxParser [URI]");
System.exit(0);
}*/
// oli public static ja metodin ulkopuolella
System.setProperty("javax.xml.parsers.SAXParserFactory",
"org.apache.xerces.jaxp.SAXParserFactoryImpl");
//String uri = args[0];
String uri = "src\\gamelib\\Gamelibrary.xml";
try {
if (outF.askName())
outF.openFile(); // ok, avataan tiedosto
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setValidating(true);
parserFactory.setNamespaceAware(false);
parserFactory.setFeature(
"http://apache.org/xml/features/validation/schema", true);
MySaxParser MySaxParserInstance = new MySaxParser();
SAXParser parser = parserFactory.newSAXParser();
parser.parse(uri, MySaxParserInstance);
}
catch (IOException exception) {
exception.printStackTrace();
}
catch (SAXException exception) {
exception.printStackTrace();
}
catch (ParserConfigurationException exception) {
exception.printStackTrace();
}
catch (FactoryConfigurationError exception) {
exception.printStackTrace();
}
System.out.println("Prasing done.");
}
public void characters(char[] ch, int start, int length) throws SAXException {
String s = new String(ch, start, length);
s = s.trim();
switch(element){
case 1:
peli.setName(s);
break;
case 2:
peli.setStudio(s);
break;
case 3:
peli.setGenre(s);
break;
case 4:
peli.setPlaform(s);
break;
case 5:
peli.setPublished(s);
break;
//outF.write(s); jos halutaan printata tiedostoon nin tämä käyttöön
}
}
public void endDocument() throws SAXException {
}
public void endElement(String url, String localName, String qName) throws
SAXException {
System.out.println("Loppuva elementti: "+qName);
if (qName.equals("game"))
Pelit.AddGame(peli);
}
public void startDocument() throws SAXException {
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Alkava elementti: "+qName);
switch(qName){
case "name":
element = 1;
break;
case "studio":
element = 2;
break;
case "genre":
element = 3;
break;
case "platform":
element = 4;
break;
case "published":
element = 5;
break;
case "game":
peli = new Game();
break;
}
}
public void fatalError(SAXParseException e) throws SAXException {
throw new java.lang.UnsupportedOperationException(
"Method fatalError() not yet implemented.");
}
和存储类
public class Game {
private static String Name, Studio, Genre, Plaform, Published;
public String getName() {return Name;}
public String getStudio() {return Studio;}
public String getGenre() {return Genre;}
public String getPlaform() {return Plaform;}
public String getPublished() {return Published;}
public void setName(String Name) {this.Name = Name;}
public void setStudio(String Studio) {this.Studio = Studio;}
public void setGenre(String Genre) {this.Genre = Genre;}
public void setPlaform(String Plaform) {this.Plaform = Plaform;}
public void setPublished(String Published) {this.Published = Published;}
}
我已经调试了无数次代码,用它尝试了难以言喻的东西,现在我不知所措
我想澄清一下。调试表明
peli.setName
确实执行了正确的值,比如说“Derp”,并且它确实注册到了Game.Name
,但是如果我在调试过程中再进一步,值会从“Derp”变为“”。我不完全清楚您的问题,但我认为问题出在这里:
解析器多次调用characters
方法,其中一些方法只包含空格字符或不包含字符
对违法者:
<foo>
<bar>The Text I Want</bar>
</foo>
我想要的文本
在上面的XML中,解析器可以在
和
之间自由调用字符,并且它将包含一些空白(如果XML已格式化,则为制表符和新行)
在存储从字符
检索到的信息之前,应该验证您是否在正确的元素中。我通常通过保留一个表示我在xml层次结构中的位置的堆栈来实现这一点
此外,一次调用字符
可能不会返回元素中的所有字符。XML解析器可以将元素的字符拆分为多个字符事件。这意味着您需要使用startElement
和endElement
事件来创建/刷新使用characters
方法写入的缓冲区。重要提示:在重写方法之前添加@Override,如startElement
。如果签名中有错误,编译器错误会说:不重写任何方法。现在,如果参数类型错误,将调用DefaultHandler的startElement
此外,字符
可能会被多次调用:
保存字符串变量
private StringBuilder elementValue;
在startElement中,请执行以下操作:
elementValue = new StringBuilder()
和字符,无需修剪:
elementValue.append(s);
在endElement中保存它,使用现在的字符
peli.setName(elementValue.toString());
这是因为叶元素没有内部标记。下面是发生的情况。。。方法characters
对于元素的内容不一定只调用一次。字符数据可能会被节点(如注释、CDATA节、处理指令等)分解。即使情况并非如此,并且元素的内容是一个文本块,XML解析器也可能会决定将其分块读取,在换行符处将其拆分,甚至在某个时刻为您提供空字符串
相反,您需要做的是保留一个StringBuilder或类似的缓冲区,在调用characters
方法时追加指定的char[],并且仅在调用methodendElement
后使用其完整值。之后,您可以清空构建器,并在下一个元素中再次使用它
我还有一些额外的建议给你。不需要将classGame
中的字段设置为静态。对我来说,这些看起来应该是实例字段。我不知道这是否是学习如何编写SAX处理程序的任务或练习,但如果不是,而且这是一个更大项目的一部分,我强烈建议您考虑使用JAXB,它非常适合从XML到Java对象,反之亦然。尝试了无法形容的东西。您对计算机做了什么?!能否包含xml输入文件的副本?这里有一个指向.xml文件的链接:)这只是一个练习:)不过还是看了看JAXB。我并没有真正理解所有的文档(作为一个编码新手),但仍然会尝试同样的任务。谢谢你的提示!还需要补充的是,我用JAXB从头开始构建了整个系统,经过一点实验,JAXB似乎是一种相当简单有效的编组和解编组方法;)杰出的这样的技术可以让你避免重新发明轮子。虽然JAXB在高级使用中确实有一些棘手的细节,但它是一种很好的技术,可以放在您的工具箱中。非常感谢!这些答案解决了问题!我不确定在这种情况下使用什么作为缓冲区,但使用StringBuilder
确实解决了整个问题=)