使用具有多个条件Java的XPath在特定标记内读取

时间:2014-03-13 09:23:26

标签: java xml xpath xml-parsing

<?xml version="1.0" encoding="UTF-8"?>
-<ADOXML adoversion="Version 5.1" username="kvarga" database="adonisdb" time="08:55"   date="30.11.2013" version="3.1">
-<MODELS>
-<MODEL version="" applib="ADONIS BPMS BP Library 5.1" libtype="bp" modeltype="Business process model" name="Product development" id="mod.25602">
 -<MODELATTRIBUTES>
<ATTRIBUTE name="Version number" type="STRING"> </ATTRIBUTE>
<ATTRIBUTE name="Author" type="STRING">kvarga</ATTRIBUTE>
<ATTRIBUTE name="Creation date" type="STRING">2013-11-30, 08:50</ATTRIBUTE>
<ATTRIBUTE name="Date last changed" type="STRING">2013-11-30, 08:54:46</ATTRIBUTE>

-<INSTANCE name="Business Opportunities census" id="obj.25615" class="Activity">
<ATTRIBUTE name="Position" type="STRING">NODE x:6.5cm y:10.5cm index:7</ATTRIBUTE>

<ATTRIBUTE name="External tool coupling" type="STRING"> </ATTRIBUTE>
<ATTRIBUTE name="Description" type="STRING">I WANT THIS PARA 1</ATTRIBUTE>


<ATTRIBUTE name="Version number" type="STRING"> </ATTRIBUTE>
<ATTRIBUTE name="Author" type="STRING">kvarga</ATTRIBUTE>
<ATTRIBUTE name="Creation date" type="STRING">2013-11-30, 08:50</ATTRIBUTE>
<ATTRIBUTE name="Date last changed" type="STRING">2013-11-30, 08:54:46</ATTRIBUTE>

-<INSTANCE name="Business Opportunities census" id="obj.25615" class="Activity">
<ATTRIBUTE name="Position" type="STRING">NODE x:6.5cm y:10.5cm index:7</ATTRIBUTE>
<ATTRIBUTE name="Description" type="STRING">I WANT THIS PARA 2</ATTRIBUTE>
</INSTANCE>


 </MODEL>

 </MODELS>

 </ADOXML>

Hye我想阅读这个xml文件,需要获取标签内的文本:

 <ATTRIBUTE name="Description" type="STRING">

我一直在尝试使用我的代码获取结果:

 DocumentBuilderFactory builderFactory =
    DocumentBuilderFactory.newInstance();
  DocumentBuilder builder = null;
try {

builder = builderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = builder.parse(
        new FileInputStream("c:\\y.xml"));

        XPath xPath =  XPathFactory.newInstance().newXPath();

       String expression = "/ADOXML/MODELS/MODEL/MODELATTRIBUTES/ATTRIBUTE[@name='Description'and @type='STRING']";
   System.out.println(expression);
   NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue()); 
}


} catch (ParserConfigurationException | SAXException | IOException e) {
System.out.print(e);
}       

我的代码存在问题,无法弄清楚是什么!

如果我使用XPath表达式,我的代码工作正常:

String expression = "/ADOXML/MODELS/MODEL/MODELATTRIBUTES/ATTRIBUTE[@type='STRING']";

它工作正常但我的特定标签是:

   <ATTRIBUTE name="Description" type="STRING"> I WANT THIS PARA 1 </ATTRIBUTE>

这样输出应为:

   I WANT THIS PARA 1
   I WANT THIS PARA 2

提前致谢

4 个答案:

答案 0 :(得分:0)

试试这个:

List<String> list = new ArrayList<>();
            try {
                XPathExpression expr =
                    xpath.compile(//ATTRIBUTE[@name='description']/text()");
                NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
                for (int i = 0; i < nodes.getLength(); i++)
                    list.add(nodes.item(i).getNodeValue());
            } catch (XPathExpressionException e) {
                e.printStackTrace();
            }
            return list;

更多示例xpath with java:

public static String obtenirTextNodoMultiple(Document doc, String nodo)
  {
    String resultat = "";
    int i = 0;
    boolean trobat = true;
    try
    {
      if (doc != null)
        while ((resultat.equals("")) && (trobat)) {
          String valor = doc.getElementsByTagName(nodo).item(i).getTextContent();

          if (valor != "") {
            trobat = false;
            if (!trobat) resultat = valor;
          }
          i++;
        }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return resultat;
  }

  public static String recValorFiltreFill(String pare*father*, String nodeComparar*node to compare*, String valorAComparar*value to compare*, Document doc, String nodo*node*)
  {
    String resultat = "";
    try {
      XPath xpath = XPathFactory.newInstance().newXPath();
      XPathExpression expr = null;

      if (doc != null)
      {
        if ((pare.equals("")) && (valorAComparar.equals(""))) {
          expr = xpath.compile("//" + nodo);
        }
        else if (valorAComparar.equals("")) {
          expr = xpath.compile("//" + pare + "/" + nodo);
        }
        else {
          expr = xpath.compile("//" + pare + "[" + nodeComparar + "='" + valorAComparar + "']/" + nodo);
        }

        resultat = (String)expr.evaluate(doc, XPathConstants.STRING);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    return resultat;
  }

答案 1 :(得分:0)

为XPath尝试此表达式。

String expression = "//ADOXML//MODELS//MODEL//MODELATTRIBUTES//ATTRIBUTE[@name='Description' and @type='STRING'] | //ADOXML//MODELS//MODEL//MODELATTRIBUTES//INSTANCE/ATTRIBUTE[@name='Description' and @type='STRING']";

显示两个属性标签,其中name ='Description'1)直接在MODELATTRIBUTES标签下访问,2)在INSTANCE标签下

答案 2 :(得分:0)

我认为你所拥有的很好,你只需要在表达式的末尾添加/text()以从元素中获取文本节点。

另外,当您直接访问文本节点时,您不再需要在节点上调用getFirstChild,如果有多个文本节点,这可能会有问题!

在查找属性值时,您也可以使用eq代替=,因为它们在您的示例中始终是原子的。我也认为虽然这两种形式在语义上是等价的,但从语法上看,最好使用两个谓词背靠背而不是and(至少对我来说; - ))

String expression = "/ADOXML/MODELS/MODEL/MODELATTRIBUTES/ATTRIBUTE[@name eq 'Description'][@type eq 'STRING']/text()";

System.out.println(expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
    System.out.println(nodeList.item(i).getNodeValue()); 
}

答案 3 :(得分:0)

根据我的Given XML文件,我的XPath表达式应该是:

String expression = "/ADOXML/MODELS/MODEL/INSTANCE/ATTRIBUTE[@name='Description' and @type='STRING']";

它的作品宾果!