解析复杂的 xml

好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受。

 

中规中矩的xml解析,都么有个啥,关键是复杂点的xml解析,而且是复杂点的一类xml,结构一样,但是内容完全不同

Demo.xml:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ResponseMessage xmlns="http://www.iec.ch/TC57/2008/schema/message">
         <Header>
            <Verb>Show</Verb>
            <Noun>OMSFHYCZCJSJ</Noun>
            <User>
               <UserID>DDD系统</UserID>
               <Organization>BRUCE</Organization>
            </User>
            <Property>
               <Name>count</Name>
               <Value>50</Value>
            </Property>
         </Header>
         <Reply>
            <ReplyCode>OK</ReplyCode>
         </Reply>
         <Payload>
            <rdf:RDF xmlns:cim="http://iec.ch/TC57/CIM-generic#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
               <cim:OMSFHYCZCJSJ rdf:ID="OMSFHYCZCJSJ_0">
                  <cim:aaa>ZHOGNG</cim:aaa>
                  <cim:bbb>广州</cim:bbb>
                  <cim:ccc>2018年第23周 (06.04~06.10)</cim:ccc>
                  <cim:ddd>16500</cim:ddd>
                  <cim:eee>8800</cim:eee>
                  <cim:fff>2200000</cim:fff>
                  <cim:ggg>0</cim:ggg>
                  <cim:hhh>0</cim:hhh>
                  <cim:kkk>16500</cim:kkk>
                  <cim:mmm>2200000</cim:mmm>
               </cim:OMSFHYCZCJSJ>
            </rdf:RDF>
         </Payload>
      </ResponseMessage>
   </soapenv:Body>
</soapenv:Envelope>

 

提供公共解析,如何公共解析,

即编写公共的获取xml值的方法。具体看码:

    /**
     * 结果集.
     */
    public static Map<String,Map<String, String>> xmlDataMaps=new LinkedHashMap<String,Map<String, String>>();
    /**
     * 节点个数.
     */
    private static Map<String, String> nodeMap=new HashMap<String,String>();
    
    /**
     * 通过字符串获得结果.
     * @param strVal:xml 字符串
     * @param nodeName:节点名称
     */
    public static void getXmlValByStr(String strVal,String nodeName) {
        if (strVal==null || strVal.length()==0) {
            return;
        }
        SAXReader sax = new SAXReader();
        Document document = null;
        try {
            InputStream stream=new ByteArrayInputStream(strVal.getBytes(Constant.ENCODING));
            document = sax.read(stream);
            document.setXMLEncoding(Constant.ENCODING);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        Element root = document.getRootElement();
        //获得节点个数.
        getXmlNodes(root,nodeName);
        int nodes=nodeMap.size();
        //初始化map集合
        initMaps(nodes);
        //获得数据.
        getXmlNodesVal(root,nodeName);
    }
    
    /**
     * 通过流获得结果.
     * @param stream:流对象
     * @param nodeName:节点名称
     */
    public static void getXmlValByStream(InputStream stream,String nodeName) {
        if (stream==null) {
            return;
        }
        SAXReader sax = new SAXReader();
        Document document = null;
        try {
            document = sax.read(stream);
            document.setXMLEncoding(Constant.ENCODING);
        }
        catch (DocumentException e) {
            e.printStackTrace();
        }
        Element root = document.getRootElement();
        //获得节点个数.
        getXmlNodes(root,nodeName);
        int nodes=nodeMap.size();
        //初始化map集合
        initMaps(nodes);
        //获得数据.
        getXmlNodesVal(root,nodeName);
    }
    
    /**
     * 通过文件获得对象.
     * @param filePath:文件绝对路径
     * @param nodeName:节点名称
     */
    public static void getXmlValByFile(String filePath,String nodeName) {
        if (filePath==null || filePath.length()==0) {
            return;
        }
        SAXReader sax = new SAXReader();
        File file=new File(filePath);
        Document document = null;
        try {
            document = sax.read(file);
            document.setXMLEncoding(Constant.ENCODING);
        }
        catch (DocumentException e) {
            e.printStackTrace();
        }
        Element root = document.getRootElement();
        //获得节点个数.
        getXmlNodes(root,nodeName);
        int nodes=nodeMap.size();
        //初始化map集合
        initMaps(nodes);
        //获得数据.
        getXmlNodesVal(root,nodeName);
    }

    /**
     * 初始化map集合.
     * @param nodes:节点数据.
     */
    private static void initMaps(int nodes) {
        for (int i = 0; i < nodes; i++) {
            Map<String, String> tempValMap=new LinkedHashMap<>();
            xmlDataMaps.put(Constant.MAPTAG+i,tempValMap);
        }
    } 
    
    /**
     * 递归遍历所有子节点value
     * @param node
     * @param nodeName
     */
    @SuppressWarnings("unchecked")
    private static void getXmlNodesVal(Element node,String nodeName) {
        String tagName=node.getName();
        String tagVal=node.getTextTrim();
        String attrName ="";
        String attrValue ="";
        List<Attribute> listAttrs = node.attributes();
        for (Attribute attribute : listAttrs) {
            attrName=attribute.getName();
            attrValue=attribute.getValue();
        }
        if (tagName.equalsIgnoreCase(nodeName) && attrName.equalsIgnoreCase("ID")) {
            Map<String, String> actualVals=new LinkedHashMap<String, String>();
            String prex=nodeName+Constant.TAG;
            String key=attrValue.substring(prex.length(), attrValue.length());
            List<Element> listElement = node.elements();
            for (Element element : listElement) {
                 tagName=element.getName();
                 tagVal=element.getTextTrim();
                 actualVals.put(tagName, tagVal);
            }
            xmlDataMaps.put(Constant.MAPTAG+key,actualVals);
        }
        List<Element> listElement = node.elements();
        for (Element element : listElement) {
            getXmlNodesVal(element,nodeName);
        }
    }

    /**
     * 获得节点的个数.
     * @param root
     * @param nodeName
     * @return
     */
    @SuppressWarnings("unchecked")
    private static void getXmlNodes(Element root,String nodeName) {
        String tagName=root.getName();
        String attrName ="";
        String attrValue ="";
        List<Attribute> listAttrs = root.attributes();
        for (Attribute attribute : listAttrs) {
            attrName=attribute.getName();
            attrValue=attribute.getValue();
        }
        if (tagName.equalsIgnoreCase(nodeName) && attrName.equalsIgnoreCase("ID") && attrValue.contains(nodeName)) {
            String prex=nodeName+Constant.TAG;
            String key=attrValue.substring(prex.length(), attrValue.length());
            nodeMap.put(key,attrValue);
        }
        List<Element> listElement = root.elements();
        for (Element element : listElement) {
            getXmlNodes(element,nodeName);
        }
    }
    
    /**
     * 清除内存中的数据.
     */
    public static void clearData() {
        nodeMap.clear();
        xmlDataMaps.clear();
    }

 

如此就可以将某类复杂的xml解析完成了,并获将获得的值以key,value 的方式保存起来。

 

 

 

在实际的项目中,IPhone应用程序会存在很多与服务器之间的数据交互的地方,XML是首选方案。 此包可以解决XML文件的解析、对象转化为XML字符串的问题。 1 通过调用解析类,可以将XML的DATA数据转换为XmlNode对象,XmlNode以树形结构进行XML的数据封装,使用的时候按照树形结构进行数据的获取。(如有问题请留言) XmlNode结构如下: @interface XmlNode : NSObject { } @property(nonatomic,retain)NSMutableDictionary *attributes;//属性 @property(nonatomic,retain)NSMutableArray *childs;//下级子节点 @property(nonatomic,retain)NSString *name;//节点名称 @property(nonatomic,retain)NSString *value;//节点值 @property BOOL haveChilds;//是否有子节点 @property BOOL haveAttribute;//是否有属性 @property(nonatomic,retain)NSMutableString *xmlString; -(void)addAttribute:(NSDictionary *)att; -(void)addChild:(XmlNode *)node; -(NSString *)getXmlString;//将此对象装换为XML字符串 -(NSString *)getNodeValue:(NSString *)nodeName;//在此节点中根据子节点名称获得子节点值 -(NSString *)getAttributeValue:(NSString *)attName;//获得此节点的属性值 @end 2 而解析器只需要调用相应的方法,传入相应的参数即可。 -(XmlNode *)getObject:(NSString *)elName xmlData:(NSData *)xmlData;//从data中获取对象,并返回封装对象XmlNode 。 -(NSMutableArray *)getList:(NSString *)elName xmlData:(NSData *)xmlData;//从DATA中获得对象集合,集合中也是XmlNode --ps-- 花了点时间重构了之前的xml与对象的转换代码,采用了新的逻辑算法。代码更加精简,并可支持包含节点的属性转换了。 之前有人说看不懂是做什么,所以写了个小UI来进行体现。
XML文件比较复杂时,使用JAXB可能会变得不太方便,这时你可以使用DOM或SAX等更高级的XML解析库。下面是一个使用DOM解析复杂XML文件的示例: 1. 在pom.xml中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> ``` 2. 创建一个控制器类,使用DOM解析XML数据: ``` @RestController @RequestMapping("/api") public class XmlController { @PostMapping("/xml") public String parseXml(@RequestBody String xmlString) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(xmlString)); Document document = db.parse(is); NodeList nodeList = document.getElementsByTagName("person"); StringBuilder sb = new StringBuilder(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; String name = element.getElementsByTagName("name").item(0).getTextContent(); int age = Integer.parseInt(element.getElementsByTagName("age").item(0).getTextContent()); sb.append("Name: ").append(name).append(", Age: ").append(age).append("\n"); } } return sb.toString(); } } ``` 在上面的示例中,我们使用了DocumentBuilderFactory和DocumentBuilder来创建一个XML文档的DOM表示。然后,我们使用getNodeList方法获取所有的person元素,并逐个解析它们的子元素。 3. 使用Postman或其他HTTP客户端进行测试: 发送POST请求到http://localhost:8080/api/xml,将以下XML数据作为请求体: ``` <?xml version="1.0" encoding="UTF-8"?> <people> <person> <name>John Doe</name> <age>30</age> </person> <person> <name>Jane Smith</name> <age>25</age> </person> </people> ``` 如果一切正常,你应该会得到以下响应: ``` Name: John Doe, Age: 30 Name: Jane Smith, Age: 25 ``` 这就是使用Spring Boot解析复杂XML文件的一个示例。注意,你可以使用其他XML解析库,例如SAX,来处理更大的XML文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值