-1

XMLドキュメント内のテキスト要素の正確なXPathを見つける必要があります。これを行う1つの方法は、ドキュメントを文字列に変換し、サブ文字列の周りに一時タグを追加し、それをドキュメントに変換してからXPathを見つけることであると考えました。

これは私がこれまでに持っているものです:

public String findXPathInXMLString(int startIndex, int endIndex, String string) throws IOException, ParserConfigurationException, SAXException {
    Conversion conversion = new Conversion();
    String xpath;

    //Step 1. Replace start to end index with temporary tag in string document
    StringBuilder stringBuilder = new StringBuilder(string);
    stringBuilder.replace(startIndex, endIndex, "<findXPathInXMLStringTemporaryTag>" + string.substring(startIndex, endIndex) + "</findXPathInXMLStringTemporaryTag>");

    //Step 2. Convert string document to DOM document & Find XPath of temporary tag in DOM document
    xpath = "/" + getXPath(conversion.stringToDocument(stringBuilder.toString()), "findXPathInXMLStringTemporaryTag");

    //Step 3. Cut off last part of the XPath
    //xpath = xpath.substring(0, 2).replace("/documentXPathTemporaryTag", "");

    //Step 4. Return the XPath
    return xpath;
}

public 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;
}

public String getXPath(Node node) {
    if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
        return "";
    }
    return getXPath(node.getParentNode()) + "/" + node.getNodeName();
}

私がこれまでに抱えている問題は、メソッドgetXPathが配置しない[x]ため、返されるXPathが間違っていることです。これは、サブストリングが[3]特定のタグのrdインスタンスにある可能性があるためです。この場合、XPathはすべての同じパスを持つノード。1つの特定の要素のみを参照できる正確なパスを取得したいと思います。

4

1 に答える 1

2

了解しました。これはどうですか(ideoneの例を使用):

に変更startIndexendIndexましたindex。一時ノードは、テキスト内の1つのポイントに追加できます。

public static String findXPathInXMLString(int index, String string) throws XPathExpressionException, SAXException, ParserConfigurationException, IOException {
    String xpath;

    //Step 1. Insert temporary tag in insert location
    StringBuilder stringBuilder = new StringBuilder(string);
    stringBuilder.insert(index, "<findXPathInXMLStringTemporaryTag />");

    Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
        new ByteArrayInputStream(stringBuilder.toString().getBytes())
      );

    //Step 2. Convert string document to DOM document & Find XPath of temporary tag in DOM document
    xpath = getXPath(document, "findXPathInXMLStringTemporaryTag");

    //Step 3. Cut off last part of the XPath
    xpath = xpath.replace("/findXPathInXMLStringTemporaryTag", "");

    //Step 4. Return the XPath
    return xpath;
}

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


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

  return null;
}

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

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

private static String getIndex(Node node) throws XPathExpressionException {
    XPathExpression expr = XPathFactory.newInstance().newXPath().compile("count(preceding-sibling::*[local-name() = '" + node.getNodeName() + "'])");
    int result = (int)(double)(Double)expr.evaluate(node, XPathConstants.NUMBER);

    if(result == 0){
        return "";
    }
    else {
        return "[" + (result + 1) + "]";
    }
}
于 2013-01-22T11:35:31.117 に答える