为了账号安全,请及时绑定邮箱和手机立即绑定

从xml节点java生成/获取XPath

从xml节点java生成/获取XPath

函数式编程 2019-07-06 17:37:58
从xml节点java生成/获取XPath我对建议感兴趣伪码代码/解释而不是实际执行.我想使用xml文档,它的所有节点检查节点是否存在属性如果节点没有属性,get/generate String with value of its xpath如果节点确实有属性,那么可以迭代时隙属性列表,并为每个属性(包括节点)创建XPath。忠告?希望你能提供一些有用的情报编辑:这么做的原因是.。我正在用jmi编写自动化测试,所以对于每个请求,我都需要验证该请求是否完成了它的工作,所以我通过使用XPath获取节点值来断言结果。(额外的信息-无关)当请求很小时,手工创建断言并不是问题,但对于较大的请求来说,这是一个真正痛苦的问题。(额外信息-无关)赏金:我在找java方法目标我的目标是从这个ExXML文件中实现以下目标:<root>     <elemA>one</elemA>     <elemA attribute1='first' attribute2='second'>two</elemA>     <elemB>three</elemB>     <elemA>four</elemA>     <elemC>         <elemB>five</elemB>     </elemC></root>制作下列文件://root[1]/elemA[1]='one'//root[1]/elemA[2]='two'//root[1]/elemA[2][@attribute1='first']//root[1]/elemA[2][@attribute2='second'] //root[1]/elemB[1]='three'//root[1]/elemA[3]='four'//root[1]/elemC[1]/elemB[1]='five'解释:如果节点值/文本不是空/零,则获取XPath,为断言目的添加=‘nodevalue’如果节点有属性,那么也为它们创建断言赏金更新:我找到了这个例子,它没有产生正确的结果,但是我看起来如下所示:http:/www.coderanch.com/how-to/java/SAXCreateXPath
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

下面是如何使用SAX来完成这一任务:

import java.util.HashMap;import java.util.Map;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.
sax.XMLReader;import org.xml.sax.helpers.DefaultHandler;public class FragmentContentHandler extends DefaultHandler {

    private String xPath = "/";
    private XMLReader xmlReader;
    private FragmentContentHandler parent;
    private StringBuilder characters = new StringBuilder();
    private Map<String, Integer> elementNameCount = new HashMap<String, Integer>();

    public FragmentContentHandler(XMLReader xmlReader) {
        this.xmlReader = xmlReader;
    }

    private FragmentContentHandler(String xPath, XMLReader xmlReader, FragmentContentHandler parent) {
        this(xmlReader);
        this.xPath = xPath;
        this.parent = parent;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        Integer count = elementNameCount.get(qName);
        if(null == count) {
            count = 1;
        } else {
            count++;
        }
        elementNameCount.put(qName, count);
        String childXPath = xPath + "/" + qName + "[" + count + "]";

        int attsLength = atts.getLength();
        for(int x=0; x<attsLength; x++) {
            System.out.println(childXPath + "[@" + atts.getQName(x) + "='" + atts.getValue(x) + ']');
        }

        FragmentContentHandler child = new FragmentContentHandler(childXPath, xmlReader, this);
        xmlReader.setContentHandler(child);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        String value = characters.toString().trim();
        if(value.length() > 0) {
            System.out.println(xPath + "='" + characters.toString() + "'");
        }
        xmlReader.setContentHandler(parent);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        characters.append(ch, start, length);
    }}

它可以通过以下方法进行测试:

import java.io.FileInputStream;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.
sax.InputSource;import org.xml.sax.XMLReader;public class Demo {

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();

        xr.setContentHandler(new FragmentContentHandler(xr));
        xr.parse(new InputSource(new FileInputStream("input.xml")));
    }}

这将产生所需的输出:

//root[1]/elemA[1]='one'//root[1]/elemA[2][@attribute1='first]//root[1]/elemA[2][@attribute2='second]//root[1]/elemA[2]='
two'//root[1]/elemB[1]='three'//root[1]/elemA[3]='four'//root[1]/elemC[1]/elemB[1]='five'


查看完整回答
反对 回复 2019-07-06
?
慕后森

TA贡献1802条经验 获得超5个赞

带着jOOX(A)jQueryAPI端口到Java,免责声明-我为库后面的公司工作),您几乎可以在一条语句中实现您想要的结果:

// I'm assuming this:import static org.joox.JOOX.$;// And then...List<String> coolList = $(document).xpath("//*[not(*)]").map(
    context -> $(context).xpath() + "='" + $(context).text() + "'");

如果文档是您的示例文档:

<root>
    <elemA>one</elemA>
    <elemA attribute1='first' attribute2='second'>two</elemA>
    <elemB>three</elemB>
    <elemA>four</elemA>
    <elemC>
        <elemB>five</elemB>
    </elemC></root>

这将产生

/root[1]/elemA[1]='one'
/root[1]/elemA[2]='two'
/root[1]/elemB[1]='three'
/root[1]/elemA[3]='four'
/root[1]/elemC[1]/elemB[1]='five'

所谓“几乎”,我的意思是jOOX不支持匹配/映射属性。因此,属性不会产生任何输出。不过,这将在不久的将来实施。


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 863 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信