>  기사  >  백엔드 개발  >  XML - XML ​​구문 분석을 위한 SAX

XML - XML ​​구문 분석을 위한 SAX

黄舟
黄舟원래의
2017-02-24 15:06:591386검색

1. SAX 파싱

  • DOM을 사용하여 XML 문서를 파싱할 때는 XML 문서 전체를 읽고 빌드해야 합니다. XML 문서를 작동하기 위해 전체 DOM 트리의 메모리 Document 개체에 있습니다. 이 경우 XML 문서의 용량이 특히 크면 컴퓨터 메모리를 많이 소모하게 되며, 심한 경우에는 메모리 오버플로가 발생할 수 있습니다.

  • SAX 구문 분석을 사용하면 전체 문서가 로드될 때까지 기다릴 필요 없이 문서를 읽을 때 문서를 처리할 수 있습니다.

  • DefaultHandler

을 상속받아 SAX 파서를 개발한다. [참고] SAX 메인을 사용한다 XML 문서를 구문 분석하기 위한 것이며 요소를 수정, 삭제 또는 추가할 수 없습니다.

1.1. SAX 구문 분석 메커니즘

Sax는 푸시 메커니즘이므로 Sax 파서를 생성합니다. 파서는 XML 문서에서 콘텐츠를 찾으면 이를 알려줍니다(Java Swing의 이벤트 수신과 다소 유사하게 이벤트를 사용자에게 푸시함). 이러한 결과로 무엇을 할지 결정하는 것은 프로그래머의 몫입니다.

sax 기반 프로그램에는 가장 일반적으로 사용되는 5가지 sax 이벤트가 있습니다.

1.startDocument()–> 파서가 문서 스캔을 시작한다고 알려줍니다.
2.endDocument()–> 파서가 문서의 끝을 찾았음을 알려줍니다.
3.startElement()–> 파서가 시작 태그를 찾았음을 알려줍니다. 이 이벤트는 태그 이름, 모든 속성 이름 및 요소 값을 알려줍니다. 4.characters()–>는 파서가 일부 텍스트를 찾았음을 알려주고 문자 배열, 배열의 오프셋 및 길이 오프셋을 가져옵니다.
5.endElement()–> 파서가 종료 태그를 찾았음을 알려줍니다.

SAX 구문 분석 예

다음과 같이 DOM 구문 분석에 사용되는 XML 예제를 사용합니다.

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>

[단계]:

1. SAXParserFactory를 사용하여 SAX 구문 분석 팩토리를 만듭니다. 🎜>
SAXParserFactory spf = SAXParserFactory.newInstance();

2. SAX 파싱 팩토리를 통해 파서 개체를 얻습니다.

SAXParser sp = spf.newSAXParser();

3. 파싱 개체를 이벤트 핸들러 개체와 연결합니다.

sp.parse("src/myClass.xml",new MyHandler());

여기에

가 있어야 합니다. 직접 정의하고

을 상속받아야 하며, MyHandler 클래스에서 위에서 언급한 5개의 sax 이벤트 메서드를 다시 작성해야 합니다. 물론 필요한 것만 다시 작성할 수도 있습니다. DefaultHandler예를 들어 지금 제가 작성한 MyHandler은 다음과 같습니다.

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}
MyHandler실행 결과는 다음과 같습니다.

XML - XML ​​구문 분석을 위한 SAX보시다시피 , 이것은 XML 문서입니다. 일종의 순회가 있으며 sax가 할 수 있는 것은 순회뿐입니다.

이제 이러한 요구 사항이 있는 경우:

只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?

클래스에 두 개의 부울 변수 isName 및 isAge를 정의할 수 있습니다.

메소드에서 이름 요소인지 연령 요소인지 식별합니다. 그렇다면 다음과 같이 MyHandler 메소드에서 해당 텍스트를 가져옵니다. startElementcharacters

1. 🎜>

private boolean isName = false;private boolean isAge = false;
2.

메소드에 판정 추가

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}
startElement3. 식별자 Text

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}
를 기반으로 마지막으로 두 개의 부울 변수를 false로 재설정해야 합니다. characters실행 결과는 다음과 같습니다.


1. SAX 파싱 XML - XML ​​구문 분석을 위한 SAX

DOM을 사용하여 XML 문서 구문 분석 이를 수행하려면 전체 XML 문서를 읽고 메모리에 전체 DOM 트리의 Document 객체를 구축한 다음 XML 문서에서 작업해야 합니다. 이 경우 XML 문서의 용량이 특히 크면 컴퓨터 메모리를 많이 소모하게 되며, 심한 경우에는 메모리 오버플로가 발생할 수 있습니다.

  • SAX 구문 분석을 사용하면 전체 문서가 로드될 때까지 기다릴 필요 없이 문서를 읽을 때 문서를 처리할 수 있습니다.

  • DefaultHandler

을 상속받아 SAX 파서를 개발한다. [참고] SAX 메인을 사용한다 XML 문서를 구문 분석하기 위한 것이며 요소를 수정, 삭제 또는 추가할 수 없습니다.

1.1. SAX 파싱 메커니즘

Sax는 푸시 메커니즘입니다. Sax 파서를 생성하면 파서가 언제 알려줄 것입니다. 이는 XML 문서에서 콘텐츠를 찾습니다(Java Swing의 이벤트 수신과 다소 유사하게 사용자에게 이벤트를 푸시함). 이러한 결과로 무엇을 할지 결정하는 것은 프로그래머의 몫입니다. 색소폰 기반 프로그램에는 가장 일반적으로 사용되는 5가지 색소폰 이벤트가 있습니다.

1.startDocument()–>告诉你解析器发现了文档的开始,告诉你解析器开始扫描文档
 2.endDocument()–>告诉你解析器发现了文档结尾
 3.startElement()–>告诉你解析器发现了一个起始标签,该事件告诉你标签的名称、该元素所有的属性名和值
 4.characters()–>告诉你解析器发现了一些文本,将得到一个字符数组,该数组的偏移量和一个长度偏移量,有这三个变量你可以得到解析器发现的文本
 5.endElement()–>告诉你解析器发现了一个结束标签,该事件告诉你元素的名称

1.2.SAX解析实例

依然使用DOM解析中用到的XML例子,如下:

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>

【步骤】:

1.使用SAXParserFactory创建SAX解析工厂

SAXParserFactory spf = SAXParserFactory.newInstance();

2.通过SAX解析工厂得到解析器对象

SAXParser sp = spf.newSAXParser();

3.将解析对象和事件处理器对象关联

sp.parse("src/myClass.xml",new MyHandler());

这里的MyHandler需要自己定义,并且它要继承DefaultHandler,然后在MyHandler类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler如下:

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        
        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}

运行结果如下:

XML - XML ​​구문 분석을 위한 SAX

可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。


那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?

我们可以在MyHandler类中定义两个布尔变量isName和isAge,在startElement方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters方法中获取对应的文本,如下:

1.定义两个布尔变量

private boolean isName = false;private boolean isAge = false;

2.在startElement方法中添加判断

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        
        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}

3.在characters方法中根据标识符进行判断是否获取文本

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}

最后要记得将两个布尔变量复位成false。
运行结果如下:

XML - XML ​​구문 분석을 위한 SAX

 以上就是XML—XML解析之SAX的内容,更多相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.