2009-09-20 135 views
1

我可以对以下问题使用一些指导。整个“不允许使用XML库”部分让我陷入循环。谢谢!Java XML解析

创建一个Java程序,以XML作为输入,分析输入和 所有的元素名称写入与标签缩进 其嵌套级别控制台。你应该处理xml属性,但是你不需要显示或者解释它们。无需 处理CDATA或任何xml处理指令。不允许使用xml 库。

+0

1)请告诉我们你做了什么,哪部分是错的。 2)这是作业,是的? – CPerkins 2009-09-20 21:13:35

+3

好吧,好像你被要求写一个XML解析器! – ennuikiller 2009-09-20 21:14:03

+0

我还没有开始,但我想就从哪里开始...... – 2009-09-20 21:15:21

回答

1

标识使用测试驱动开发在这里

我会写测试,如

的assertEquals("测试",解析(" <测试/ > "));

的assertEquals("测试",解析(" <测试> < /测试> "));

的assertEquals("测试\ n \ tfun ",解析(" <测试> <乐趣> < /乐趣> < /测试> "));

等,使他们都通过。

记得处理角落案件和不良xml。

解析你可以这样做:

1)String.indexOf找到第一(<),并在循环最后一个(>)XML元素和处理里面是什么。使用递归会让你有更好的成绩。

2)你也可以使用String.split。你可以拆分第一个和最后一个XML元素或使用正则表达式来获取XML元素内部的内容。如果你知道正则表达式,2a是最容易写的,但1最好,因为它的速度更快(你可能看不到它,但听起来更快),许多老师只关心性能。

2

我不确定什么等级会困扰你。

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

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

因此,您获得的每个令牌都是左角,直角或一些没有角度的字符串。

在XML中,角度不会嵌套,这实际上可以节省很多工作量。所以我们假设你的XML看起来像这样(在代码块之外,我正在将角括号转换为parens,因为我不想输入所有的&符号废话,任何对此不舒服的人都可以编辑我的帖子,修复):

<tag var="meh">between</tag>

你的第一令牌是 “<”,然后 “标签VAR =” MEH”,然后 “>”,然后 “之间” 时,则 “<”,然后 “/标记” ,那么“>”

到目前为止还不错

您需要知道,如果您在角括号内或外界知道如何处理您的字符串,请将其作为布尔值进行跟踪。由于没有嵌套,所以一个布尔值就足够了。

您还需要了解您的标签嵌套级别。这应该会自动让你的大脑闪现单词“Stack”。堆栈是你如何实现嵌套,期限。

所以你的过程是,读一个令牌。如果它是“<”,则将内部布尔值设置为true并继续,如果是“>”,则将布尔值设置为false并继续。把这两个搞定了!你完成了一半!

接下来,如果你是,我宁愿实例具有以下属性的对象:

String tagName 
HashMap<String, String> attributes 
// Why the heck do angle-brackets correctly display here SO?!? 
String value 

并将其推入你的筹码。 (注意,LinkedList有一个Stack API)

所以你会把名字存储在“tagName”和HashMap中的变量中并继续。如果是我,这个小类将有一个构造函数接受一个字符串,并且它所用的字符串将是尖括号之间的字符串。它会解析字符串本身并在返回之前存储tagName和属性。

如果你这样做,那么你的循环,你只是说如果你是“内=真”,并且该值不是一个角括号(你知道它不是,这些案件已被删除!),然后简单地说: (哎呀,如果这个“标记”以“/”开始,你必须做一些不同的事情,继续阅读)。

非常简洁易读,不是吗?

最后,剩下的一种情况是当你在外面,你的字符串是一个标记。在这种情况下,您知道最近的堆栈条目是除“值”以外填写的XMLObject。价值应该是你现在的标志。

你完成了除印刷。

哦,我忘了,当你打你的结束标记,你需要弹出值从堆栈并打印(推开放标签,弹出关闭标签)

你可以让你的缩进级别检查堆栈的大小(stack.size()应确定要打印多少个选项卡)。

如果你真的要划分责任,我不得不实施的XMLObject格式化该数据,你想让它打印方式一个toString,那么当你到达终点的标签,所有你需要做的是:

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 

就是这样。我认为这些案例中的每一个都是1行,也许2或3,如果你不嵌入stack.push(新的XMLObject(令牌))之类的东西。

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

我尽量避免使用真正的java,所以请使用自己的风格!所描述的XMLObject类是一个非常好的主意。习惯于尽可能地创建新类(我从字面上看不到有太多类的代码)。

这是太多的帮助,但它非常有趣我可能会写一个XML解析器只是为了它的地狱。

+0

fyi:尖括号只是在代码文字之外的Markdown中使用时很痛苦。里面的代码文字,他们很直接。 – 2009-09-20 23:02:25

+0

p.s.我会将你的HashMap的名称从“变量”更改为“属性”,因为属性就是它们的名称。 – 2009-09-20 23:05:48

+0

谢谢贾森,修好了!注意:如果不明显,则不能使用=或==,必须使用.equals作为字符串。另外,你可能想要在很多东西上调用.trim(例如你的标签)。去除前导空间和尾随空间。 – 2009-09-21 00:55:47

1

有点棘手的情况下要注意的:

  • 评论例如<!-- this is a comment-->
  • 空标签(例如/>结束<element foo='1' bar='2' baz='3' />标签)
+0

Ug +1好点,我忘了那两个!猜猜他是否喜欢我的答案,他将不得不为自己弄清楚这一部分 - 尽管不太难。 – 2009-09-21 01:02:25

1

只需经过XML文件逐个字符,做你必须做的事情。

  1. 设置一些状态变量(与像等待开始标记,读取元件名,等待属性名,读取属性值,读取元件含量值 - 等待结束标记等)。

  2. 设置深度计数器(因为您需要漂亮打印)。

  3. 使用状态变量和当前字符决定如何更改状态或将新字符添加到目前为止您已阅读的内容。

  4. 假设您的XML格式良好。

您的实际任务比'XML解析器'听起来容易得多。

+0

不比XML解析器容易得多 – 2009-09-21 13:23:25