Java XML解析

Java XML解析,java,xml,Java,Xml,我可以就以下问题提供一些指导。整个“不允许使用XML库”部分让我陷入了一个循环。谢谢 创建一个java程序,将XML作为输入,解析输入并 将所有元素名称写入控制台,并使用制表符缩进到 它们的筑巢水平。您应该处理xml属性,但不需要 必须显示或以其他方式解释它们。没有必要这样做 处理CDATA或任何xml处理指令。不使用xml 图书馆是允许的 我在这里使用测试驱动开发 我会像这样写测试 assertEquals(“测试”,解析(“”) assertEquals(“测试”,解析(“”) assert

我可以就以下问题提供一些指导。整个“不允许使用XML库”部分让我陷入了一个循环。谢谢

创建一个java程序,将XML作为输入,解析输入并 将所有元素名称写入控制台,并使用制表符缩进到 它们的筑巢水平。您应该处理xml属性,但不需要 必须显示或以其他方式解释它们。没有必要这样做 处理CDATA或任何xml处理指令。不使用xml 图书馆是允许的


我在这里使用测试驱动开发

我会像这样写测试

assertEquals(“测试”,解析(“”)

assertEquals(“测试”,解析(“”)

assertEquals(“test\n\tfun”,parse(“”))

等等,让他们都通过

请记住要处理死角案例和错误的xml

您可以执行以下操作:

1) 使用String.indexOf在循环中查找first()xml元素并处理其中的内容。使用递归会让你得到更好的分数

2) 也可以使用String.split。您可以拆分第一个和最后一个xml元素,或者使用正则表达式获取xml元素的内部内容


2a是最容易做到的,如果你知道regex,2b可能是最快的,但是1是最好的,因为它更快(你可能看不到,但听起来更快),而且许多老师只关心性能。

我在这里使用测试驱动开发

我会像这样写测试

assertEquals(“测试”,解析(“”)

assertEquals(“测试”,解析(“”)

assertEquals(“test\n\tfun”,parse(“”))

等等,让他们都通过

请记住要处理死角案例和错误的xml

您可以执行以下操作:

1) 使用String.indexOf在循环中查找first()xml元素并处理其中的内容。使用递归会让你得到更好的分数

2) 也可以使用String.split。您可以拆分第一个和最后一个xml元素,或者使用正则表达式获取xml元素的内部内容


2a是最容易做到的,2b可能是最快的,如果你知道正则表达式,但是1是最好的,因为它更快(你可能看不到,但听起来更快),而且许多老师只关心表现。

我不确定是什么级别困扰着你

首先,您将迭代所有XML字符

我个人会使用StringTokenizer。我知道它有点过时,但是你可以很容易地让它解析在你感兴趣的两个尖括号字符上,你可以设置它来返回“Tokens”

因此,您获得的每个标记将是左角、右角或一些没有角度的字符串

在XML中,angle不嵌套,这实际上为您节省了很多工作

假设您的XML看起来是这样的(在代码块之外,我正在将尖括号转换为括号,因为我不想键入所有的符号和废话,任何对此感到不舒服的人都可以编辑我的帖子并修复它):

介于

您的第一个标记是“文本或非文本> 内=假; case-inside=false stack.peek().setValue(令牌) 内部大小写(内部=真) 带有“!--&”的子案例令牌启动"(完)" 评论,忽略 子案例标记以“/”开头,以“/”结尾,长度超过1个字符 创建对象,然后像找到闭合标记一样操作 子案例令牌=“” (抛出异常/打印错误/bail!//内部必须有标记!) 子案例标记。startsWtih(“/”) 创建和推送 子案例令牌不可用。开始时使用“/” 子案例长度=1(仅为斜杠,惰性关闭标记) 流行与印刷 子案例长度>1 打印错误,除非(stack.peek().getTagName().equals(tagWithoutSlash)) 流行与印刷 就这样。我认为每种情况都是1行,如果不嵌套像stack.push(newXMLObject(token))这样的东西,可能是2或3行

我本来不会提供这么多,但它比我想象的要复杂,因为我包括了所有的错误检查和东西

我尽量避免使用真正的java,所以请使用您自己的风格!不过,如上所述的XMLObject类是一个非常好的主意。养成在任何可能的地方创建新类的习惯(我从来没有见过包含太多类的代码)


这帮助太多了,但它太有趣了,我可能会编写一个XML解析器来解决这个问题。

我不确定是什么级别让您感到困扰

首先,您将迭代所有XML字符

我个人会使用StringTokenizer。我知道它有点过时,但是你可以很容易地让它解析在你感兴趣的两个尖括号字符上,你可以设置它来返回“Tokens”

因此,您获得的每个标记将是左角、右角或一些没有角度的字符串

在XML中,angle不嵌套,这实际上为您节省了很多工作

假设您的XML看起来是这样的(在代码块之外,我正在将尖括号转换为括号,因为我不想键入所有的符号和废话,任何对此感到不舒服的人都可以编辑我的帖子并修复它):

介于

您的第一个标记是“文本或非文本> 内=假; case-inside=false stack.peek().setValue(令牌) 内部大小写(内部=真) 带有“!--&”的子案例令牌启动"(完)" 评论,忽略 子案例标记以“/”开头,以“/”结尾,长度超过1个字符 创建对象,然后像找到闭合标记一样操作 子案例令牌=“” (抛出异常/打印错误/bail!//内部必须有标记!) 子案例标记。startsWtih(“/”) 创建和推送 子案例令牌不可用。开始时使用“/” 子案例长度=1(仅为斜杠,惰性关闭标记) 流行与印刷 子案例长度>1 打印错误,除非(stack.peek().getTagName().equals(tagWithoutSlash)) 流行与印刷 就这样。我认为每种情况都是1行,如果不嵌套像stack.push(newXMLObject(token))这样的东西,可能是2或3行

String tagName
HashMap<String, String> attributes 
// Why the heck do angle-brackets correctly display here SO?!?
String value
push(new XMLObject(token));  
Pop the XMLObject.
Print out stack.size() tabs (use print not println!)
Print XMLObject.toString();
case token = "<" //note, if already "inside", this is an error
  if(inside) throw exception // Indicates < tagname <
  inside=true; 
case token = ">" 
  if(!inside) throw exception // Indicates > text or not >
  inside=false;
case inside = false
  stack.peek().setValue(token)
case inside (inside = true)      
  sub-case token startsWith "!-- & endsWith "--"
    comment, ignore
  sub-case token startsWith "/" and endsWith "/" and is more than 1 char long
    create the object, then act as though you found a close tag
  sub-case token = "" 
    (throw exception/print error/bail! // inside must have a tag!)
  sub-case token.startsWtih("/")         
    create & push
  sub-case token doesn't .startWith "/"
    sub-sub-case length=1 (just the slash, lazy close tag)
      pop & print
    sub-sub-case length > 1
      print an error unless (stack.peek().getTagName().equals(tagWithoutSlash))
      pop & print