Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当Xml节点文本具有有趣的字符时,会导致问题_Java_Xml_Sax_Xerces - Fatal编程技术网

Java 当Xml节点文本具有有趣的字符时,会导致问题

Java 当Xml节点文本具有有趣的字符时,会导致问题,java,xml,sax,xerces,Java,Xml,Sax,Xerces,我将在以下事件中设置xml元素中的字符: public void characters(char[] ch, int start, int length) { elementText = new String(ch, start, length); } 其中elementText是一个字符串 <client-key>#&lt;ABC::DEF::GHI:0x102548f78&gt;</client-key> 现在,如果我更改

我将在以下事件中设置xml元素中的字符:

 public void characters(char[] ch, int start, int length) {
        elementText = new String(ch, start, length);
    }
其中elementText是一个字符串

<client-key>#&lt;ABC::DEF::GHI:0x102548f78&gt;</client-key>
现在,如果我更改上面元素
中的文本,它在我的objects属性中会很好地显示出来

是否有一些编码问题需要我以某种方式处理

public void endElement(String uri, String localName, String qName) {

       if (qName.equals("client-key")) {
            client.setClientKey(elementText);
        }

}

如果您的xml已整理为如下所示,则可能会得到以下结果:

<client-key>
    #&lt;ABC::DEF::GHI:0x102548f78&gt;
</client-key>

它很好用。但正如他所说,节点的内容分为多个块。所以你需要附加它。下面的示例显示了使用和不使用cdata时的输出

public class XMLTest {

    public static void main(String argv[]) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {

                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                }

                public void endElement(String uri, String localName, String qName) throws SAXException {
                }

                public void characters(char ch[], int start, int length) throws SAXException {
                    System.out.println(new String(ch, start, length));
                }
            };
            saxParser.parse("test.xml", handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

<?xml version="1.0"?>
<company>
    <staff>
        <client-key>#&lt;ABC::DEF::GHI:0x102548f78&gt;</client-key>    
        <client-key><![CDATA[#<ABC::DEF::GHI:0x102548f78>]]></client-key>    
    </staff>
</company>

因此,您可以使用CDATA或append。

XML解析器通常使用两个阶段来处理文档中的数据。在第一阶段,文档(字节序列)被解码成一系列字符,这些字符被放入输入缓冲区。实际的XML解析在第二阶段完成,在该阶段中分析不同的结构,如元素开始和结束标记。请注意,这两个阶段是并行执行的。更准确地说,随着XML解析的进行,输入缓冲区会根据需要重新填充。还要注意,如果文档已经作为字符序列提供(例如,使用
StringReader
),则跳过第一阶段的解码,但解析器仍将使用输入缓冲区存储从流中读取的字符

正如其他人所指出的,SAX解析器不需要将文本节点报告为单个块。它可以自行决定将节点拆分为多个块。这称为非合并解析

你所谓的“有趣的角色”实际上是角色实体引用(在你的例子中也是如此)。在将数据发送到应用程序之前,需要对它们进行解码(在您的情况下为“”。然而,这只能在第二阶段完成。原因是,如果相同的字符序列(例如“')出现在不同的上下文中,特别是在CDATA节中,则可能不需要解码

关键是,如果文本节点不包含任何实体引用,那么解析器可以将字符数据直接从输入缓冲区传递到应用程序。这增加了将整个文本节点报告为单个块的可能性。然而,即使在这种情况下,文本节点也可能不完全适合输入缓冲区,在这种情况下,解析器将以多个块的形式报告它


另一方面,如果文本节点包含实体引用,则解析器无法将数据直接从输入缓冲区传递到应用程序,因为部分数据需要进一步解码。为了避免多次复制数据,大多数解析器将选择将不需要进一步解码的部分直接传递给应用程序,而实体引用首先解码到单独的缓冲区中。这就是为什么原始文档中的块由实体引用分隔。

您需要发布更多用于“将此xml数据加载到java对象”的代码,以及用于在XML元素中设置字符的代码。@artbristol我粘贴了用于填充对象字段的endElement事件中的代码。这会导致什么问题?看起来有趣吗?抛出异常?打破时空连续体?@PaulButcher是的,请看我的问题,文本显示为“\n”这一定是编码问题,只是不确定如何设置正确的编码。常见的SAX处理错误,请参阅+1。在遇到
endElement
事件之前,必须以
字符
的形式累积数据。那你就知道你有所有的角色。还要注意,正如
characters
方法文档中所述:“任何单个事件中的所有字符必须来自同一外部实体”但是,当我把“有趣的字符”改成字母数字句子时,为什么它会起作用呢?@Blankman-如果你发布更多的代码,我们也许能解决问题,但如果你尝试一下,它会更快。@Blankman
字符的行为(是否返回多个数据块)是依赖于实现的,您不希望您的代码依赖于这样的东西。所以每个人在使用
字符和那些不会暴露于bug的字符时都应该使用某种形式的累积。为什么我会突然收到反对票<代码>请
在否决投票时发表评论,否则我将如何学习做得更好?
public void characters(char[] ch, int start, int length) {
  // Note the +=
  elementText += new String(ch, start, length);
}

public void endElement(String uri, String localName, String qName) {

  if (qName.equals("client-key")) {
    client.setClientKey(elementText);
  }
  elementText = "";
}
public class XMLTest {

    public static void main(String argv[]) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {

                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                }

                public void endElement(String uri, String localName, String qName) throws SAXException {
                }

                public void characters(char ch[], int start, int length) throws SAXException {
                    System.out.println(new String(ch, start, length));
                }
            };
            saxParser.parse("test.xml", handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

<?xml version="1.0"?>
<company>
    <staff>
        <client-key>#&lt;ABC::DEF::GHI:0x102548f78&gt;</client-key>    
        <client-key><![CDATA[#<ABC::DEF::GHI:0x102548f78>]]></client-key>    
    </staff>
</company>
#
<
ABC::DEF::GHI:0x102548f78
>


#<ABC::DEF::GHI:0x102548f78> 
<client-key>testing</client-key>
testing