使用XMLBean中的XMLCursor实现对XML文档的XPath和XQuery查询和修改

因为在对XML数据操作上要用到XPath 和XQuery, 所以编写的工具要支持XPath和XQuery语法。XMLBean 对XQuery和XPath提供了完整支持。

本例使用的是XMLBean2.2。读者需要saxon8.xml, saxon8-dom.xml, xbean_xpath.jar来运行本例。 这些jar包都包含在了XMLBean2.2下载包中。

XMLBean功能强大,因此不可能在这里详细阐述。读者可以访问 XMLBean主页。在这里我只是针对XMLBean中XMLObject和XMLCursor类在XPath和XQuery中的应用给出一些实例。

XMLObject接口对应于一个XML文档中的 xs:anyType类型。XMLObject是所有XMLBean类的基础类。

参考XMLObject的API文档

XMLCursor接口在使用上类似JDBC中的SQL Cursor,对当前文档创建了一个指针。用户就可以基于指针的位置进行数据的处理和对文挡中的元素进行搜索。因为是接口,所以用户不能直接生成XMLCursor实例。用户需要调用当前XMLObject的newCursor()方法来创建针对该XMLObject的XMLCursor实例。

参考XMLCursor的API文档

 

下面给出的例子使用XMLObject和XMLCursor编写了一个对XML文件做XPath处理的工具:

主要方法:

parseXml() - 将xml文档转化为xmlObject实例

getXpathValue() - 获取单个XPath的文本值,Xpath如果返回多个值则取第一个

getXpathValues() - 获取所有XPath的文本值,返回值放入数组中.

getXpathElement() - 获取单个XPath的元素对象,Xpath如果返回多个值则取第一个

getXpathElements() - 获取所有XPath的元素对象,返回值放入数组中.

setXpathValue() - 修改单个XPath位置的值,Xpath如果返回多个值则取第一个

<span style="font-size:18px;">package com.agilelogicsolutions.util;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

public class CursorHelper {
    static boolean verbose = false;

    public CursorHelper() {
    }

    /**
     * Parses the XML File
     *
     * @param xmlFilePath
     * @return
     */
    public XmlObject parseXml(String xmlFilePath) {
        File xmlFile = new File(xmlFilePath);
        XmlObject xml = null;
        try {
            xml = XmlObject.Factory.parse(xmlFile);
        } catch (XmlException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xml;
    }

    public XmlObject parseXml(InputStream is) {
        XmlObject xml = null;
        try {
            xml = XmlObject.Factory.parse(is);
        } catch (XmlException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return xml;
    }

    /**
     * Used to get the value from a specific XPath in the namespace
     *
     * @param xml
     * @param nameSpace
     * @param xpath
     * @return
     */
    public String getXPathValue(XmlObject xml, String nameSpace, String xpath) {
        // Create a temporary cursor for the XPath passed in
        XmlCursor xpathCursor = xml.newCursor();

        // Create a formatter to format the XPath
        StringBuilder builder = new StringBuilder();
        Formatter formatter = new Formatter(builder);
        formatter.format("%s %s", nameSpace, xpath);

        // Select the XPath
        xpathCursor.selectPath(formatter.toString());
        xpathCursor.toNextSelection();

        // Using ternary operation - if selection count >0 then return the value
        // else return null
        String pathValue = xpathCursor.getSelectionCount() > 0 ? xpathCursor
                .getTextValue() : null;

        // We don't need the cursor any more... dispose of it
        xpathCursor.dispose();

        // Logging
        if (verbose) {
            builder = new StringBuilder();
            Formatter msgFormatter = new Formatter(builder);
            System.out.println(msgFormatter.format(
                    "Value %-35s XPath expression: %s %s", pathValue,
                    nameSpace, xpath));
        }
        return pathValue;
    }

    /**
     * Used to get the value from a specific XPath in the namespace
     *
     * @param xml
     * @param nameSpace
     * @param xpath
     * @return
     */
    public String[] getXPathValues(XmlObject xml, String nameSpace, String xpath) {
        // Create a temporary cursor for the XPath passed in
        XmlCursor xpathCursor = xml.newCursor();
        List<String> pathValues = new ArrayList<String>();
        // Create a formatter to format the XPath
        StringBuilder builder = new StringBuilder();
        Formatter formatter = new Formatter(builder);
        formatter.format("%s %s", nameSpace, xpath);

        // Select the XPath
        xpathCursor.selectPath(formatter.toString());

        while (xpathCursor.toNextSelection()) {
            // Using ternary operation - if selection count >0 then return the value
            // else return null

            pathValues.add(xpathCursor.getSelectionCount() > 0 ? xpathCursor.getTextValue() : null);
        }

        // We don't need the cursor any more... dispose of it
        xpathCursor.dispose();
        // Logging
        if (verbose) {
            builder = new StringBuilder();
            Formatter msgFormatter = new Formatter(builder);
            System.out.println(msgFormatter.format(
                    "Value %-35s XPath expression: %s %s", pathValues.toString(),
                    nameSpace, xpath));
        }
        return pathValues.toArray(new String[pathValues.size()]);
    }

    /**
     * Used to get the whole element from a specific XPath in the namespace
     *
     * @param xml
     * @param nameSpace
     * @param xpath
     * @return
     */
    public XmlObject getXPathElement(XmlObject xml, String nameSpace, String xpath) {
        // Create a temporary cursor for the XPath passed in
        XmlCursor xpathCursor = xml.newCursor();

        // Create a formatter to format the XPath
        StringBuilder builder = new StringBuilder();
        Formatter formatter = new Formatter(builder);
        formatter.format("%s %s", nameSpace, xpath);

        // Select the XPath
        xpathCursor.selectPath(formatter.toString());
        xpathCursor.toNextSelection();

        // Using ternary operation - if selection count >0 then return the value
        // else return null
        XmlObject pathElement = xpathCursor.getSelectionCount() > 0 ? xpathCursor.getObject() : null;

        // We don't need the cursor any more... dispose of it
        xpathCursor.dispose();

        // Logging
        if (verbose) {
            builder = new StringBuilder();
            Formatter msgFormatter = new Formatter(builder);
            System.out.println(msgFormatter.format(
                    "Value %-35s XPath expression: %s %s", pathElement.toString(),
                    nameSpace, xpath));
        }
        return pathElement;
    }

    /**
     * Used to get the whole element from a specific XPath in the namespace
     *
     * @param xml
     * @param nameSpace
     * @param xpath
     * @return
     */
    public XmlObject[] getXPathElements(XmlObject xml, String nameSpace, String xpath) {
        // Create a temporary cursor for the XPath passed in
        XmlCursor xpathCursor = xml.newCursor();
        List<XmlObject> pathElements = new ArrayList<XmlObject>();

        // Create a formatter to format the XPath
        StringBuilder builder = new StringBuilder();
        Formatter formatter = new Formatter(builder);
        formatter.format("%s %s", nameSpace, xpath);

        // Select the XPath
        xpathCursor.selectPath(formatter.toString());

        while (xpathCursor.toNextSelection()) {
            // Using ternary operation - if selection count >0 then return the value
            // else return null
            pathElements.add(xpathCursor.getSelectionCount() > 0 ? xpathCursor.getObject() : null);
        }

        // We don't need the cursor any more... dispose of it
        xpathCursor.dispose();

        // Logging
        if (verbose) {
            builder = new StringBuilder();
            Formatter msgFormatter = new Formatter(builder);
            System.out.println(msgFormatter.format(
                    "Value %-35s XPath expression: %s %s", pathElements.toString(),
                    nameSpace, xpath));
        }
        return pathElements.toArray(new XmlObject[pathElements.size()]);
    }

    /**
     * Used to set the value to a specific XPath in the namespace
     *
     * @param xml
     * @param nameSpace
     * @param xpath
     * @param value
     * @return
     */
    public XmlObject setXPathValue(XmlObject xml, String nameSpace, String xpath, String value) {
        // Create a temporary cursor for the XPath passed in
        XmlCursor xpathCursor = xml.newCursor();

        // Create a formatter to format the XPath
        StringBuilder builder = new StringBuilder();
        Formatter formatter = new Formatter(builder);
        formatter.format("%s %s", nameSpace, xpath);

        // Select the XPath
        xpathCursor.selectPath(formatter.toString());
        xpathCursor.toNextSelection();

        // Using ternary operation - if selection count >0 then return the value
        // else return null
        if (xpathCursor.getSelectionCount() > 0)
            xpathCursor.setTextValue(value);

        // We don't need the cursor any more... dispose of it
        xpathCursor.dispose();

        // Logging
        if (verbose) {
            builder = new StringBuilder();
            Formatter msgFormatter = new Formatter(builder);
            System.out.println(msgFormatter.format(
                    "XPath value at %s %s is updated to: %s", nameSpace, xpath, value));
        }
        return xml;
    }


    public static void main(String[] args) {
        CursorHelper cursor = new CursorHelper();
        XmlObject xml = cursor.parseXml("C:/My_Dir/mySample.xml");
        String value = cursor.getXPathValue(xml,
                "declare namespace s11='http://schemas.xmlsoap.org/soap/envelope/'; ",
                "$this/s11:Envelope/s11:Body/*/s11:ResponseHeader/s11:Status/s11:StatusCode");
        System.out.println("Value is: " + value);
    }
    
}
</span>

上例主要使用了XMLCursor中的selectPath()方法来实现XPath调用。使用selectPath()后,程序并不返回当前位置的值,只是把指针移动到指定的XPath位置。然后通过toNextSelection()方法选定要返回的XML元素,最后使用getObject()或者getTextValue()方法返回XML对象或是文本值。类似的,对于XQuery调用,则使用executeQuery()方法。executeQuery()返回一个包含XQuery结果的XMLCurosr指针。值得注意的是XMLBean对命名空间的要求。所有XPath和XQuery请求都需要给出相应的命名空间。可以参考上例中的main()方法查看如何实现一个具体的XPath请求

 通过XMLCursor,用户可以轻松访问XML文档,对内容进行查询和修改。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用`@Autowired`注解自动装配时,需要确保以下三个条件满足: 1. Spring容器必须能够扫描到该bean,即该bean必须已经被实例化并注册到Spring容器。 2. 该bean必须具有默认的构造函数。 3. 该bean必须被标注为`@Component`或其它相关注解。 如果使用XML配置生成的bean,可以使用`<context:component-scan>`元素扫描包路径,将标注为`@Component`或其他相关注解的类自动纳入Spring容器,如下所示: ```xml <context:component-scan base-package="com.example"/> ``` 如果使用注解生成的bean,需要在配置类上添加`@ComponentScan`注解,指定需要扫描的包路径,如下所示: ```java @Configuration @ComponentScan(basePackages = "com.example") public class AppConfig { // ... } ``` 在使用`@Autowired`注解自动装配时,可以在成员变量、构造函数或方法参数上使用该注解,如下所示: ```java @Service public class MyService { @Autowired private MyDao myDao; public MyService(MyDao myDao) { this.myDao = myDao; } @Autowired public void setMyDao(MyDao myDao) { this.myDao = myDao; } } ``` 需要注意的是,`@Autowired`注解默认情况下是按照类型进行自动装配的,如果存在多个同类型的bean,需要使用`@Qualifier`注解指定具体的bean名称,如下所示: ```java @Service public class MyService { @Autowired @Qualifier("myDaoImpl") private MyDao myDao; } ``` 以上就是使用`@Autowired`注解自动装配XML和注解生成的bean的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值