0

以下のようなXMLドキュメントがある場合:

<foo>
   <foo1>Foo Test 1</foo1>
   <foo2>
       <another1>
           <test10>This is a duplicate</test10>
       </another1>
   </foo2>
   <foo2>
       <another1>
           <test1>Foo Test 2</test1>
       </another1>
   </foo2>
   <foo3>Foo Test 3</foo3>
   <foo4>Foo Test 4</foo4>
</foo>

<test1>たとえば、のXPathを取得するにはどうすればよいですか?したがって、出力は次のようになります。foo/foo2[2]/another1/test1

コードは次のようになると思います。

public String getXPath(Document document, String xmlTag) {
   String xpath = "";
   ...
   //Get the node from xmlTag
   //Get the xpath using the node
   return xpath;
}

としましょうString XPathVar = getXPath(document, "<test1>");。次のコードで機能する絶対xpathを取得する必要があります。

XPath xpath = XPathFactory.newInstance().newXPath(); 
XPathExpression xpr = xpath.compile(XPathVar); 
xpr.evaluate(Document, XPathConstants.STRING); 

//test1ただし、メタデータの目的でも使用されるため、のようなショートカットにすることはできません。

結果を次の方法で印刷する場合:

System.out.println(xpr.evaluate(Document, XPathConstants.STRING));

ノードの値を取得する必要があります。それで、もしそうならXPathVar = foo/foo2[2]/another1/test1、私は戻るべきです:

Foo Test 2ではなくThis is a duplicate

4

2 に答える 2

2

SQLを「取得」しないのと同じ方法でxpathを「取得」しません。

xpath は、xml ドキュメントまたはスキーマの理解に基づいて作成するクエリです。SQL がデータベース スキーマの理解に基づいて作成するクエリであるように、どちらも「取得」しません。

特定のノードからノードをさかのぼることで、DOM から xpath ステートメントを生成することは可能ですが、これを一般的に行うには、各ノードの属性値を考慮に入れて、結果のコードをほとんど役に立たなくします。例(これにより、指定された名前を持つ最初のノードが検出されるという警告が表示されます。 xpath はこれよりもはるかに多く、 xpath を使用することもできます//foo2):

import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class XPathExample 
{
  private static String getXPath(Node root, String elementName)
  {
    for (int i = 0; i < root.getChildNodes().getLength(); i++)
    {
      Node node = root.getChildNodes().item(i);

      if (node instanceof Element)
      {
        if (node.getNodeName().equals(elementName))
        {
          return "/" + node.getNodeName();
        }
        else if (node.getChildNodes().getLength() > 0)
        {
          String xpath = getXPath(node, elementName);
          if (xpath != null)
          {
            return "/" + node.getNodeName() + xpath;
          }
        }
      }
    }

    return null;
  }

  private static String getXPath(Document document, String elementName)
  {
    return document.getDocumentElement().getNodeName() + getXPath(document.getDocumentElement(), elementName);
  }

  public static void main(String[] args) 
  {
    try 
    {
      Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
        new ByteArrayInputStream(
          ("<foo><foo1>Foo Test 1</foo1><foo2><another1><test1>Foo Test 2</test1></another1></foo2><foo3>Foo Test 3</foo3><foo4>Foo Test 4</foo4></foo>").getBytes()
        )
      );

      String xpath = "/" + getXPath(document, "test1");
      System.out.println(xpath);        

      Node node1 = (Node)XPathFactory.newInstance().newXPath().compile(xpath).evaluate(document, XPathConstants.NODE);
      Node node2 = (Node)XPathFactory.newInstance().newXPath().compile("//test1").evaluate(document, XPathConstants.NODE);

      //This evaluates to true, hence you may as well just use the xpath //test1.
      System.out.println(node1.equals(node2));
    }
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
}

同様に、xml ドキュメントを一連の xpath ステートメントに変換する XML 変換を作成することもできますが、この変換は、最初に xpath を作成するよりも複雑であり、ほとんど意味がありません。

于 2013-01-21T10:04:56.720 に答える
0

これはどうですか:

private static String getXPath(Document root, String elementName)
{
  try{
      XPathExpression expr = XPathFactory.newInstance().newXPath().compile("//" + elementName);
      Node node = (Node)expr.evaluate(root, XPathConstants.NODE);

      if(node != null) {
          return getXPath(node);
      }
  }
  catch(XPathExpressionException e) { }

  return null;
}

private static String getXPath(Node node) {
    if(node == null || node.getNodeType() != Node.ELEMENT_NODE) {
        return "";
    }

    return getXPath(node.getParentNode()) + "/" + node.getNodeName();
}

これは、最初に (XPath を使用して) ノードを検索し、次に検索されたノードを使用してその XPath を取得することに注意してください。すでに持っている価値を得るには、かなり遠回りのアプローチです。

動作するアイデアの例: http://ideone.com/EL4783

于 2013-01-21T11:28:15.400 に答える