Java 字符串变量在传递到另一个对象时会失去其值

Java 字符串变量在传递到另一个对象时会失去其值,java,class,variables,Java,Class,Variables,我正试图为学校项目构建一个简单的程序,将xml文件转换成对象,反之亦然。我试图将从标记之间获得的xml数据存储到一个对象中,然后将该对象存储到另一个类的另一个对象中。问题是,每次我试图将xml解析中的一些字符串传递给第一个存储对象(如名称、平台等)时,它们的值都会丢失。字符串确实被传递到存储对象,但存储只是从“XXXXXX”变为“”。我们的指挥官和我都无法解决这个问题。有什么想法吗 下面是造成混乱的类 public class MySaxParser extends DefaultHandler

我正试图为学校项目构建一个简单的程序,将xml文件转换成对象,反之亦然。我试图将从标记之间获得的xml数据存储到一个对象中,然后将该对象存储到另一个类的另一个对象中。问题是,每次我试图将xml解析中的一些字符串传递给第一个存储对象(如名称、平台等)时,它们的值都会丢失。字符串确实被传递到存储对象,但存储只是从“XXXXXX”变为“”。我们的指挥官和我都无法解决这个问题。有什么想法吗

下面是造成混乱的类

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[],并且仅在调用method
endElement
后使用其完整值。之后,您可以清空构建器,并在下一个元素中再次使用它


我还有一些额外的建议给你。不需要将class
Game
中的字段设置为静态。对我来说,这些看起来应该是实例字段。我不知道这是否是学习如何编写SAX处理程序的任务或练习,但如果不是,而且这是一个更大项目的一部分,我强烈建议您考虑使用JAXB,它非常适合从XML到Java对象,反之亦然。

尝试了无法形容的东西。您对计算机做了什么?!能否包含xml输入文件的副本?这里有一个指向.xml文件的链接:)这只是一个练习:)不过还是看了看JAXB。我并没有真正理解所有的文档(作为一个编码新手),但仍然会尝试同样的任务。谢谢你的提示!还需要补充的是,我用JAXB从头开始构建了整个系统,经过一点实验,JAXB似乎是一种相当简单有效的编组和解编组方法;)杰出的这样的技术可以让你避免重新发明轮子。虽然JAXB在高级使用中确实有一些棘手的细节,但它是一种很好的技术,可以放在您的工具箱中。非常感谢!这些答案解决了问题!我不确定在这种情况下使用什么作为缓冲区,但使用
StringBuilder
确实解决了整个问题=)