使用 sax 获取内部 xml

Posted

技术标签:

【中文标题】使用 sax 获取内部 xml【英文标题】:Taking inner xml using sax 【发布时间】:2012-12-31 18:08:56 【问题描述】:

我有一个这样的 xml:

<Message xmlns="uri_of_message">
  <VendorId>1234</VendorId>
  <SequenceNumber>1</SequenceNumber>
  ...other important headers...
  <Data>
    <Functions xmlns="uri_of_functions_subxml">
      <Function1 attr="sth">
        <Info>Some_Info</Info>
      </Function1>
      <Function2>
        <Info>Some_Info</Info>
      </Function2>
      ...Functions n...
    </Functions>
  </Data>
</Message>

我需要提取内部xml

<Functions xmlns="uri_of_functions_subxml">
  <Function1 attr="sth">
    <Info>Some_Info</Info>
  </Function1>
  <Function2>
    <Info>Some_Info</Info>
  </Function2>
  ...Functions n...
</Functions>

我首先尝试使用字符方法获取内部 xml:

 public void startElement(String uri, String localName, String tagName, Attributes attributes) throws SAXException 
if (tagName.equalsIgnoreCase("Data"))
  buffer = new StringBuffer();

public void characters(char[] ch, int start, int length) throws SAXException 
  if (buffer != null) 
     buffer.append(new String(ch, start, length).trim());
  

public void endElement(String uri, String localName, String tagName) throws SAXException 
if (tagName.equalsIgnoreCase("Data"))
innerXML = buffer.toString().trim();

但后来我意识到characters方法没有正确收集xml,它可能拒绝了“”等特殊字符。

下面的链接包含相同的问题,但答案不适用于我,因为外部 xml 必须作为握手信号处理,内部 xml 必须以完全不同的方式处理。

Java XML parsing: taking inner XML using SAX

我唯一需要的是正确收集内部 xml。但是,怎么做呢? 提前谢谢..

【问题讨论】:

您似乎不了解 SAX 的工作原理。您不能将 XML 标记视为 characters 方法的内容。此方法只会获取 XML 文档的 文本节点(标签之间的内容)。您的问题似乎更像是StAX 的工作,而不是 SAX。如果您准备好接受非 SAX 答案,我将向您展示如何做到这一点。 我刚开始接触 SAX 的时候不明白的是,当 SAX 框架在 xml 文档中遇到不同类型的东西时调用的回调函数。 【参考方案1】:

SAX 似乎不是这项工作的最佳选择,无论如何尝试一下

    SAXParser p = SAXParserFactory.newInstance().newSAXParser();
    XMLReader filter = new XMLFilterImpl(p.getXMLReader()) 
        private boolean inFunctions;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException 
            if (!inFunctions && qName.equals("Functions")) 
                inFunctions = true;
            
            if (inFunctions) 
                super.startElement(uri, localName, qName, atts);
             else 
                qName.equals("Functions");
            
        

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException 
            if (inFunctions) 
                super.endElement(uri, localName, qName);
                if (qName.equals("Functions")) 
                    inFunctions = false;
                
            
        

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException 
            if (inFunctions) 
                super.characters(ch, start, length);
            
        
    ;
    Transformer t = TransformerFactory.newInstance().newTransformer();
    Source source = new SAXSource(filter, new InputSource(new FileInputStream("1.xml")));
    Result result = new StreamResult(System.out);
    t.transform(source, result);

输出

<?xml version="1.0" encoding="UTF-8"?><Functions xmlns="uri_of_functions_subxml">
      <Function1 attr="sth">
        <Info>Some_Info</Info>
      </Function1>
      <Function2>
        <Info>Some_Info</Info>
      </Function2>
    </Functions>

Official Tutorial

【讨论】:

以上是关于使用 sax 获取内部 xml的主要内容,如果未能解决你的问题,请参考以下文章

使用 SAX Parser,获取属性的值

使用 SAX 解析器时如何获取父节点?

使用 SAX 解析器解析 Xml

java webserver-xml--熟悉SAX解析流程-存储

XML-入门级

使用 Sax Parser、Java 处理 XML 中的空标签