SAX学习笔记

最近因为做一套SSO框架,需要解析SAML报文,研究了一下openSAML发现其需要1.5以上的jdk,于是决定自己做解析程序。在网上比较了一番dom和sax后,决定用sax来解析,因为我们更关注的是报文中某些个属性值,而不是报文的结构。闲话少叙,下面开始SAX的学习。

首先我们先了解一下SAX的基本概念。SAX是Simple Api for XML的缩写,相比与DOM,SAX是一种轻量级的XML访问方法。DOM在处理xml文档时,我们需要读入整个文档,在内存中创建dom树。在文档比较小的时候这没有什么问题,但随着文档的增大,dom的访问效率以及内存占用都会出现问题,这时,SAX就是比较好的替代方案。SAX不同于DOM的文档驱动,它是事件驱动的,在解析过程中,它不需要读入整个文档,文档读入的过程就是解析过程。所谓的事件驱动,是一种基于回调机制的程序运行方法。在解析之前,先注册一个ContentHandler,相当于一个事件监听器,其中定义了很多方法,用以处理在读取文档各个部分时要做的事情,比如startDocument(),它定义了解析过程中,遇到文档开始时所作的事情。当XMLReader读取到合适的内容,就会抛出相应的事件,把内容交给ContentHander去处理。在网上搜索SAX资料时,找到了一个简单的例子,很清晰的说明了SAX解析过程。我们来看这个简单的xml文件

<POEM>
<AUTHOR>Ogden Nash</AUTHOR>
<TITLE>Fleas</TITLE>
<LINE>Adam</LINE>
</POEM>


SAX的解析过程:

[table]
|遇到的项目 | 方法回调
|{文档开始} | startDocument()
|<POEM> | startElement(null,"POEM",null,{Attributes})
|"\n" | characters("<POEM>\n...", 6, 1)
|<AUTHOR> | startElement(null,"AUTHOR",null,{Attributes})
|"Ogden Nash" | characters("<POEM>\n...", 15, 10)
|</AUTHOR> | endElement(null,"AUTHOR",null)
|"\n" | characters("<POEM>\n...", 34, 1)
|<TITLE> | startElement(null,"TITLE",null,{Attributes})
|"Fleas" | characters("<POEM>\n...", 42, 5)
|</TITLE> | endElement(null,"TITLE",null)
|"\n" | characters("<POEM>\n...", 55, 1)
|<LINE> | startElement(null,"LINE",null,{Attributes})
|"Adam" | characters("<POEM>\n...", 62, 4)
|</LINE> | endElement(null,"LINE",null)
|"\n" | characters("<POEM>\n...", 67, 1)
|</POEM> | endElement(null,"POEM",null)
|{文档结束} | endDocument()
[/table]

SAX提供了一个DefaultHandler类,其中所有方法为空实现,我们要做的就是创建一个自己的Handeler类继承DefaultHandler,然后重载其中的startDocument()、startElement()、characters()、endElement()等方法来自己的处理。

现在我们来动手做个解析SAML AuthnRequest报文的例子,首先来看报文

<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="id_1"
Version="2.0"
IssueInstant="2007-12-05T09:21:59Z">
<saml:Issuer>https://www.chinamobile.com/SSO</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>


我们要把其中的ID、IssueInstant、Issuer、AllowCreate、Format属性解析出来,放到一个java对象中。 首先我们定义一个AuthRequest对象,其中包含上面的属性以及get、set方法

	
static class AuthRequest {
private String id;
private String issueInstant;
private String issuer;
private String allowCreate;
private String format;
public void setID(String id){
this.id = id;
}
public void setIssueInstant(String issueInstant){
this.issueInstant = issueInstant;
}
public void setIssuer(String issuer){
this.issuer = issuer;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAllowCreate() {
return allowCreate;
}
public void setAllowCreate(String allowCreate) {
this.allowCreate = allowCreate;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public String getIssueInstant() {
return issueInstant;
}
public String getIssuer() {
return issuer;
}
@Override
public String toString() {
return "id="+id+",issueInstant="+issueInstant+",issuer="+issuer;
}
}


然后我们创建自己的handler MyHandler


static class MyHandler extends DefaultHandler {

private AuthRequest request;
private Stack stack;

public MyHandler(AuthRequest request){
this.request = request;
this.stack = new Stack();
}

@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
stack.push(name);
if ("samlp:AuthnRequest".equalsIgnoreCase(name)){
for (int i = 0;i < attributes.getLength();i ++){
if ("ID".equalsIgnoreCase(attributes.getQName(i))){
request.setID(attributes.getValue(i));
}else if ("IssueInstant".equalsIgnoreCase(attributes.getQName(i))){
request.setIssueInstant(attributes.getValue(i));
}
}
}else if ("samlp:NameIDPolicy".equalsIgnoreCase(name)){
for (int i = 0;i < attributes.getLength();i ++){
if ("AllowCreate".equalsIgnoreCase(attributes.getQName(i))){
request.setAllowCreate(attributes.getValue(i));
}else if ("Format".equalsIgnoreCase(attributes.getQName(i))){
request.setFormat(attributes.getValue(i));
}
}
}

}

@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
stack.pop();
}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if ("saml:Issuer".equalsIgnoreCase((String)stack.peek())){
request.setIssuer(new String(ch,start,length));
}
}
}

这里我们用了一个stack来保存当前解析的节点信息。因为标准的xml每个标签都一定有一个对应的结束标签,我们在startElement时把标签名称push到stack中,在endElement时pop出来,这样就可以获取当前解析的标签在文档中的位置。
最后我们来执行代码

public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
AuthRequest request = new AuthRequest();
parser.parse(new File("src/xml/req.xml"), new MyHandler(request));
System.out.println(request);
}

得到输出:[i]id=id_1,issueInstant=2007-12-05T09:21:59Z,issuer=https://www.chinamobile.com/SSO[/i]

这里我们完成了一个简单的将XML转成JAVA对象的例子。可以看出,SAX提供的是一套比DOM更为基础的XML解析API,通过自定义Handler,我们可以自己控制xml解析过程,只解析我们关心的信息。当然具体用DOM,还是SAX,还是要根据实际情况去选择。
xacml4j-opensaml:XACMLOpenSAML集成 XACML / OpenSAML集成 适用于项目的实现。 Travis CI上的持续集成状态: 立即下载

相关推荐

招标信息爬取工具

一个能帮你节省大量时间的实用小工具,我自己用了挺久,分享出来给有需要的朋友

qq_56877290的博客 837

java解析XML(4种方式)

========================================== xml文件 <?xml version="1.0" encoding="GB2312"?>  <RESULT>  <VALUE>     <NO>A1234</NO>     <ADDR>四川省XX县XX镇XX路X段XX号</ADDR>  </VALUE>  <VALUE>     <NO>B1

rwb0123的专栏 552

国内合规开通ChatGPT Plus实操指南:银行卡绑卡与支付全解析

ChatGPT Plus 是 OpenAI 官方推出的高级订阅服务,基于 GPT-4o 多模态大模型提供语音交互、图像理解与长上下文处理能力。其核心使用前提在于完成合规的国际支付绑定,而非网络接入方式。技术原理上,OpenAI 采用 Stripe 支付网关进行风控校验,重点匹配银行跨境权限、卡片类型(仅支持 Visa/Mastercard/Amex 信用卡)、BIN 号段及地理位置一致性。该机制决定了95%的绑卡失败源于银行端配置缺失或卡片不兼容,而非网络问题。实际应用中,PayPal 作为中间支付层可显著

chuannaoxuan4674的博客 2002

saml2.0 java 例子_SAML 2.0 实例分析 idp向sp发送响应(4)

当idp与user建立起联系后,idp向sp发送响应>http://localhost:8080/idp>http://localhost:8080/idpvFGoJhHTVDDvkRz9bezf9+zhEBs=DuvgFw+uqHeMZr5y/1iF29ZNB6Gt6Vj6IqyIN4wR0Ty5EVd2iaYREQxIRv+/xLoko7XiO4o3bkFs6g/mlDc3Bs81...

weixin_35555531的博客 1674

uniCloud云存储进阶:七牛云扩展存储从开通、绑定域名到批量上传的完整实战

本文详细介绍了uniCloud云存储进阶实践,重点讲解如何通过七牛云扩展存储实现从开通、绑定域名到批量上传的完整流程。内容涵盖成本优势分析、域名备案方案、SSL证书配置、多文件并发上传控制等实战技巧,并提供可直接复用的代码示例,帮助开发者高效构建内容社区类应用。

weixin_26985923的博客 469

第1章 机器人SLAM算法工程师主要做什么的?(附SLAM学习路线及资料推荐)

对于想从事机器人与自动驾驶领域的在校大学生、研究生来说,建图定位算法工程师是一个极具发展潜力的岗位,而SLAM知识体系则是胜任该岗位的核心支撑。从基础的计算机工具、C++语言,到核心的开源框架、数学知识,再到硬件衔接与项目实践,每一个环节都不可或缺。建议大家结合自身兴趣确定侧重方向(如激光SLAM、融合定位),先通过开源项目建立实践认知,再补全理论知识,同时积极参与社区交流。

行知SLAM 955

opensaml2.0 java例子_OpenSAML 使用引导 I : 简介——关于OpenSAML你所需知道的一切

1. 用户尝试获得权限流程首先从一个非认证的用户开始,该用户尝试从一个受保护的SP那里获得访问权限。某种方式的过滤器被设置在访问路径上来检测用户是否被授权(J2ee中servlet类就是一个很好地例子)。这一部分其实并不是SAML协议里的内容,但是却决定了是否要被授权。2. 用户被重定向到IDP当访问路径上被设置的过滤器发现用户并非是被认证的,将会自动把用户从定向到IDP,以求验证用户的身份。3....

weixin_39557087的博客 2154

注意力机制模块:CVPR 2026 新宠:MLLA(多尺度线性注意力)即插即用,在 YOLO 和 ConvNeXt 上全面涨点

MLLA核心创新点与实践价值摘要(146字) 清华大学LeapLab团队通过解构Mamba模型,发现其核心优势源于遗忘门机制与块设计,而非传统SSM架构。基于此提出的MLLA模块创新性地将这两项设计融入线性注意力框架:1)用位置编码替代循环计算保留遗忘门的位置感知能力;2)通过门控投影+DWConv+MLP重构高效块结构。在COCO检测任务中,MLLA使小目标AP提升11.6%而仅损失6%FPS,支持ONNX/TensorRT全链路部署,代码已开源。该工作为高分辨率视觉任务提供了近乎零代价的性能提升方案。

ZXSXJ的博客 155

Java & xml学习笔记 SAX篇

Java & XML学习笔记1、需要软件   java,解析器(例如Xerces),API(例如SAX,DOM)2、SAX机制  1)解析    String xmlURI = "c:/test.xml";    String vendorParserClass = "org.apache.xerces.parsers.SAXParser";    XMLReaer reader = XMLRea

4286

【Halcon-1D测量】measure_pairs 函数功能(用于提取垂直于矩形/环形弧主轴的直边对)

HALCON算子measure_pairs是1D测量模块的基础工具,专用于提取垂直于矩形/环形弧主轴的直边对。该算子通过振幅阈值和灰度过渡规则(如positive/negative)进行边对分组,支持_strongest后缀选择最强边缘避免误配对。输出包含边缘坐标、振幅及内外间距(IntraDistance/InterDistance)。关键限制包括仅适用于直边、Sigma需≤0.5×测量长度,且忽略图像域。相比模糊版本算子,它更适用于边缘清晰的简单场景(如电子元件间距测量)。典型应用需配合gen_meas

weixin_45590420的博客 305

C/C++基础讲解(四十三)之图形篇之绘制直线、圆、圆弧、 椭圆

程序主要是基于Visual studio 2019进行编译完成了,有兴趣的小伙伴可以自己安装下Visual studio 2019,网上有现成的教程,当然了,如果有问题,也可以和我联系,这里我们主要讲解些源码实例,不多说了,言归正传。 C语言,做为学习其他语言的基础语言,其重要性就不言而喻了.下面我将和大家一起来学习探讨C语言的相关奥秘。 实例1:绘制直线 实例2:绘制圆 实例2:绘制圆弧 实例2:绘制椭圆

hnjzfwy的博客 1235

SAX之Java实现学习笔记(一)

SAX之Java实现学习笔记(一) 本文假设读者对XML有些了解 首先,先给出一个比较基本的处理xml文件的程序。你不必细看,直接跳过即可。需要时可以返回来看。  Echo01.java import java.io.*; import org.xml.sax.*;import org.xml.sax.helpers.DefaultHandler;

jzk_sherlock的专栏 1172

YOLO11改进-注意力-引入自调制特征聚合模块SMFA

SMFA(自调制特征聚合模块): SMFA模块用于协同建模局部和非局部信息,它分为两个分支:一个是EASA(Efficient Approximation of Self-Attention,简化的自注意力分支),用于捕获非局部信息;另一个是LDE(Local Detail Estimation,局部细节估计分支),用于捕获局部细节。EASA通过对输入特征进行下采样,然后利用全局特征的方差进行调制,再与原始特征进行聚合,提取非局部结构信息。LDE分支则通过卷积操作提取输入特征中的高频局部信息。

qq_64693987的博客 2208

学习笔记-dom4j和sax

 SAX篇:SAX是什么:SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。通俗点说就是用来解析xml文件的接口。SAX特点:SAX是一个用于处理XML事件驱动的“推”模型,SAX解析器不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。它逐行扫描文档,一边扫...

Sunmeok的博客 2524

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

SAX解析xml学习笔记[1]

Java类:TestXmlSAXHandler (监听器)package hello.xml;import org.xml.sax.helpers.DefaultHandler;import org.xml.sax.helpers.XMLReaderFactory;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;im

Blog内容迁移至dolphin8.cn 1382

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android学习笔记之XML解析(SAX)

SAX是一种占用内存少且解析速度快的解析器,它采用的是事件启动,它不需要解析完整个文档,而是按照内容顺序 看文档某个部分是否符合xml语法,如果符合就触发相应的事件,所谓的事件就是些回调方法(callback),这些方法 定义在ContentHandler中,下面是其主要方法: startDocument:当遇到文档的时候就触发这个事件 调用这个方法 可以在其中做些预处理工作

落日小屋 1477

学习笔记-理解sax

SAX 是什么? 用于读取和操作 XML 文件的标准是文档对象模型(Document Object Model,DOM)。遗憾的是,DOM 方法涉及读取整个文件并将该文件存储在一个树结构中,而这样可能是低效的、缓慢的,并且很消耗资源。 一种替代技术就是 Simple API for XML,或称为 SAX。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。 ...

软件设计 308

JavaWeb学习笔记——SAX解析

import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; //================================================= // File Name : MySAX /...

weixin_33720452的博客 111

sax方式解析XML学习笔记

原理:对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素开始与结束、文档结束等地方 通知事件处理函数,由事件处理函数相应动作然后继续同样的扫描,直至文档结束。 优点:消耗资源比较少;适合大文件解析; 缺点:只能读取不能修改;开发复杂。 实例:   xml    <?xml version="1.0" encoding="UTF-8"?><stude...

weixin_34148340的博客 121

Java使用SAX解析xml文件详解,【学习笔记】JAVA之使用SAX解析XML文件

思路:SAX工厂-->SAX解析器-->SAX阅读器-->注册事件处理-->解析开始。对应代码:public class TestSAX {public static void main(String[] args) throws Exception{SAXParserFactory factory = SAXParserFactory.newInstance();SAXP...

weixin_30740019的博客 164

SAX之Java实现学习笔记(二)

那我们去看看Parser(org.xml.sax.Parser)去, 看到Parser的代码,你会大失所望。原来Parser也只是一个空壳子而已  图中你可以看到经过层层查找的Parser只是一个接口而已。 回想一下前面看到生成解析器代码的时候使用了工厂模式              SAXParserFactory factory = SAXParse

jzk_sherlock的专栏 1046

【学习笔记】JAVA之使用SAX解析XML文件

思路:SAX工厂-->SAX解析器-->SAX阅读器-->注册事件处理-->解析开始。 对应代码: public class TestSAX { public static void main(String[] args) throws Exception{ SAXParserFactory factory = SAXParserFactory.newInstance();

一头不安分的蜗牛 465

xml&dom_sax_dom4j学习笔记(一)SAX解析XML文件

SAX 解析XML:          SAX与DOM不同,在解析XML文件时是边解析边处理的。解析过程为先生产一个解析工厂(SAXParserFactory),由工厂生产一个解析器(SAXParser),再由解析器生产阅读器(XMLReader),通过阅读器的parser(String systemId)方法解析XML文件。 SAX2核心的处理程序基类有四个ContentHand

Shally's Room 506

Java之SAX 方式解析 XML(学习笔记)

SAX解析原理: 程序设计步骤: SAXxmlMain.java: package com.ytu.main; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import j

Growth Diary 1430
上一篇: java多线程设计模式详解之四--线程池与工作队列
caip
博客等级 码龄22年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值