2012-02-04 75 views
0

我的代码不检索包含特殊字符的整个元素节点。 例如,对于这个节点:用Java读取包含特殊字符(&, - 等)的XML文档节点

<theaterName>P&G Greenbelt</theaterName> 

它只会检索“P”由于符号。我需要检索整个字符串。

这里是我的代码:

public List<String> findTheaters() { 

    //Clear theaters application global 
    FilmhopperActivity.tData.clearTheaters(); 

    ArrayList<String> theaters = new ArrayList<String>(); 

    NodeList theaterNodes = doc.getElementsByTagName("theaterName"); 

    for (int i = 0; i < theaterNodes.getLength(); i++) { 

     Node node = theaterNodes.item(i); 
     if (node.getNodeType() == Node.ELEMENT_NODE) { 

      //Found theater, add to return array 
      Element element = (Element) node; 
      NodeList children = element.getChildNodes(); 
      String name = children.item(0).getNodeValue(); 
      theaters.add(name); 

      //Logging 
      android.util.Log.i("MoviefoneFetcher", "Theater found: " + name); 

      //Add theater to application global 
      Theater t = new Theater(name); 
      FilmhopperActivity.tData.addTheater(t); 
     } 
    } 

    return theaters; 
} 

我尝试添加代码扩展名字符串来连接额外的children.items,但没有奏效。我只会得到“P &”。

... 
String name = children.item(0).getNodeValue(); 
for (int j = 1; j < children.getLength() - 1; j++) { 
    name += children.item(j).getNodeValue(); 
} 

谢谢你的时间。


UPDATE: 找到一个函数调用正常化(),您可以在节点调用,它结合了所有文本子节点这样一个children.item(0)包含了所有的儿童,包括与符号的文字!

+0

简单地说,&XML不允许在XML内容中使用,因此您尝试解析的XML无效。 – dbrin 2012-02-04 04:08:25

回答

5

&是XML中的转义字符。 XML看起来像这样:

<theaterName>P&G Greenbelt</theaterName> 

实际上应该被解析器拒绝。相反,它应该是这样的:

<theaterName>P&amp;G Greenbelt</theaterName> 

有几个这样的字符,如<(&≤),>(& 1+),"(& QUOT)和'(&者; )。还有其他方法可以转义字符,例如通过Unicode值,如&#x2022;或&#12345 ;.

欲了解更多信息,XML specification是相当清楚。

现在,它可能是另一件事,取决于你的树是如何构建的,正确转义的字符,并且你展示的样本不是实际存在的,它是如何表示数据的在树上。

例如,当使用SAX构建树时,实体(&-things)被分解并分开传递。这是因为SAX解析器试图返回连续的数据块,并且当它到达转义字符时,它会发送它所具有的内容,并开始一个新的块,其中包含已翻译的&值。因此,您可能需要在树中组合连续的文本节点才能获得整个值。

+0

我从Web动态检索我的XML。获取Document对象之后替换所有转义字符的最佳方法是什么? – Dan 2012-02-04 04:08:56

+0

请注意,只有在用这些字符引用的属性中,“quot”和“apos”必须表示为实体。 – beerbajay 2012-02-04 09:08:20

+0

@Dan您提取的XML是否将它们转换为未转义?您应该让该XML的生产者纠正它,因为无效的XML是由标准中的定义而不是实际的XML定义的。如果不可能让生产者修复它,那么你必须在本地提取文件,比如说读取一个字符串,然后做一个搜索和替换。但是,如果它正确地转义,你的XML解析器应该为你处理所有的细节。 – lavinio 2012-02-04 20:05:46

0

您需要对其进行正确编码或将其包装在CDATA部分。我会推荐前者。

0

数值字符引用"&#60;""&#38;"可以用于当它们发生在字符数据逃脱<&
所有的XML处理器必须识别这些实体是否被声明。对于interoperability,有效的XML文档应该在使用它们之前声明这些实体,就像任何其他实体一样。如果实体ltamp被声明,它们必须被声明为internal entities的替换文字是character reference到相应的字符(小于符号或符号)被转义;对于这些实体,双重转义是REQUIRED,因此对它们的引用会产生良好结果。如果声明了实体gt,aposquot,则它们的必须被声明为internal entities,其替换文本是被转义的单个字符(或对该字符的字符引用;这里的双重转义是可选的但是无害的)。例如:

<!ENTITY lt  "&#38;#60;"> 
<!ENTITY gt  "&#62;"> 
<!ENTITY amp "&#38;#38;"> 
<!ENTITY apos "&#39;"> 
<!ENTITY quot "&#34;"> 
2

您试图阅读的文件是无效的XML。没有自尊的XML解析器会接受它。

我从Web动态检索我的XML。获取Document对象之后替换所有转义字符的最佳方法是什么?

您正在采取错误的做法。正确的做法是通知负责创建该文件的人员,使其无效,并要求他们修复该文件。简单地写入黑客(尝试修复)破坏的XML不在您(或其他人)的长期利益之中。

如果您决定忽略了这个建议,那么一种方法是把文件读入一个字符串,使用String.replaceAll(正则表达式,替换)用合适的正则表达式来把这些假"&"字符转换成正确的字符实体("&amp;") ,然后将固定的XML字符串提供给XML解析器。您需要仔细设计正则表达式,以便它不会将有效的字符实体分解为不需要的副作用。第二种方法是手动进行解析和替换,使用适当的启发式方法来区分伪造字符实体中的伪造字符"&"

但是这一切都需要花费开发和测试时间,并且会降低软件的运行速度。更糟糕的是,由于您努力补偿不良输入文件,您的代码将变得非常脆弱。 (并猜测谁将会受到指责......)