2010-08-22 92 views
3

目前,这将是我工作的一个示例XML:我不想解析某些标签XML

<smsq> 
    <sms> 
    <id>96</id> 
    <to>03333560511</to> 
    <msg> danial says: hahaha <space> nothing. 
    </msg> 
    </sms> 
</smsq> 

现在,请注意,该标签可以包含其他标签(这不应该被解析),我必须为此做一个dtd。 DTD中是这样的:

<!DOCTYPE smsq [ 
    <!ELEMENT sms (mID,to,msg,type)> 
    <!ELEMENT mID (#PCDATA)> 
    <!ELEMENT to (#PCDATA)> 
    <!ELEMENT msg (CDATA)> 
]> 

但问题是,XML解析器还是那张在标签和说,标签应与标签关闭。我只是想从XML获取数据,我不想进一步解析msg。

请帮我解决问题,并告诉我这是否可以用DTD完成。

谢谢!

+0

如果标签不是封闭的,它不是XML。为了使XML可用,它必须是*格式正确*和*有效*。每个XML解析器都必须*拒绝输入的XML,如果它不是格式良好的*,并且缺少结束标记意味着它确实没有良好的形式。这一般取决于XML的广泛适用性和可用性。 – Abel 2010-08-22 18:17:51

+0

@Abel,它不一定是有效的可用。在很多情况下,格式良好就足够了。 – 2010-08-22 18:19:38

+0

@Jon:这是非常真实的,但是如果存在DTD,就像在这种情况下一样,XML必须是有效的才能被解析。 //只检查:无效的XML必须报告为*错误*,但这些错误不是*致命错误*,因为格式良好,即解析可以继续。 – Abel 2010-08-22 18:24:28

回答

1

首先,示例xml不是真正的xml,因为“space”标记未关闭。

其次,它看起来不想分析“空间”标签的原因是因为它不是真的xml - 只是看起来像xml的文本。文本应该被转义/编码或包含在CDATA标签中。

最后 - 如果你想解析的确实是xml,而你只想解析第一级标签。我不会打扰一个真正的XML解析器 - 我会创建我自己的超简单解析器 - 它所要做的就是解析一级节点 - 这不应该太难。

祝你好运!

+0

只要节点中的数据位于CDATA区域,就可以使用DTD完成...... – 2010-08-22 18:07:35

+0

@Hojou:没有,CDATA内部没有解析,也不能用DTD定义。但是,如果您想使用DTD并定义非关闭(即打开)元素,您可以*,但它不再是XML。这是一个SGML的实现,它很难与(像经典的HTML) – Abel 2010-08-22 18:22:00

+0

@Abel一起工作:这就是我的观点 - 如果它在CDATA中,他将不必担心分析器试图解析它。 – 2010-08-23 07:20:39

3

DTD不能帮你解决这个问题。决不要求DTD(尽管它非常方便)。

您在上面发布的文档不是有效的XML文档。期。就是这样,没有合理的XML解析器会为你解析它而不会引起错误。

你可以做的是将<符号替换为&lt; XML实体。

+0

没有冒犯,但是我用简单的英文写了这个,“我不想解析XML中的一些标签“期间。 – 2010-08-31 02:48:54

4

你不能制作一个DTD,使得越野车XML神奇不是越野车。 XML格式不完整,所以它不可能是有效的,因为格式良好是有效性的先决条件(AFAICT的有效性甚至不重要)。这与英语句子中的单词必须全部是英语单词,才能成为一个格式正确的英语句子是类似的。

<space>未关闭。它应该在<msg>中有以下</space>,用<space/>代替,或者如果说你不希望它被伪造,那么你的意思是你需要实际文本"<space>"在那里,那么你应该编码它(即&lt;space&gt;) 。

+0

你能告诉我php中的编码函数和java中的解码函数吗? – 2010-08-28 03:02:25

1

所有XML标签必须关闭,或者像<tag></tag><tag />

如果你想<space>标签被解析为标签的文本值,而不是作为一个子标签,使用&lt;&gt;代替<>

&lt;space&gt; 
+1

只需注意,'>'不需要转义(尽管这样做很常见)。 – Abel 2010-08-22 18:20:25

0

我会隔离解决方案把你的问题变成一种方法,现在就处理它。毕竟,您可能无法控制消息内容的正确性。

private static String getMessage(String msg){ 
    return msg.substring(msg.indexOf("<msg>")+5, msg.lastIndexOf("</msg>")); 
}//method 

随着更多用例可用,您可以稍后再加强它。

编辑:如果有人把一个“味精”元素的内容,那么它仍然有效

+0

然后当有人在内容中放置“味精”元素?如果他们没有必要的控制来修复错误的XML,那么他们需要首先定义**,然后精确地定义**它可能是多么的错误。 – 2010-08-22 21:14:40

+0

处理XML的程序员不太可能将其作为字符串处理。如果他们这样做,它不是XML,或者他们犯了一个巨大的错误,或者两者兼而有之。只有很少的用例将XML作为字符串处理,这不是其中之一(为了让您的示例正常工作,您首先必须修复XML,然后解析XML,然后转到该元素,然后将该元素转换为文本,然后使用你的函数(需要修复,如Jon所说),然后在需要时将其解析为XML)。 – Abel 2010-08-22 21:55:03

+0

Jon Hanna:该方法查找第一个“”和最后一个“”。向消息内容添加“msg”标签不会破坏此代码。 Abel:你提出的“让我的例子工作的变化”似乎没有更有效。 – 2010-08-23 16:04:48