Java:在XPath evaluate中使用XPath变量

huangapple go评论86阅读模式
英文:

Java : Xpath variable in xpath evaluate

问题

public Map<String, String> getAllClassesDetails() throws XPathExpressionException {

        Map<String, String> data = new HashMap<>();
        XPath xpath = XPathFactory.newInstance().newXPath();
        NodeList nodesClasses = (NodeList) xpath.evaluate("/Plan/featureMember/node()", document, XPathConstants.NODESET);

        for (int i = 0; i < nodesClasses.getLength(); i++) {
            String rawXPath = String.format("/Plan/featureMember/%s/node()", nodesClasses.item(i).getNodeName());
            NodeList nodesDetails = (NodeList) xpath.evaluate(rawXPath, document, XPathConstants.NODESET);
            for (int j = 0; j < nodesDetails.item(i).getChildNodes().getLength(); j++) {
                data.put(nodesClasses.item(i).getNodeName(), nodesDetails.item(j).getNodeName());
            }
        }

        return data;
}
<?xml version="1.0" encoding="UTF-8"?>
<Plan>
    <featureMember>
        <TestA>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestA>
        <TestB>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestB>
        <TestC>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestC>
    </featureMember>
</Plan>

Error:

javax.xml.xpath.XPathExpressionException: javax.xml.transform.TransformerException: A location step was expected following the '/' or '//' token

How can I specify a variable in xpath.evaluate?

EDIT: Here's my XML file:

<?xml version="1.0" encoding="UTF-8"?>
<Plan>
    <featureMember>
        <TestA>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestA>
        <TestB>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestB>
        <TestC>
            <Objet></Objet>
            <nature>03</nature>
            <mastery>5</mastery>
        </TestC>
    </featureMember>
</Plan>
英文:

I wouldike to get nodes of nodes in my xml file :

public Map&lt;String, String&gt; getAllClassesDetails() throws XPathExpressionException {

        Map&lt;String, String&gt; data = new HashMap&lt;&gt;();
        XPath xpath = XPathFactory.newInstance().newXPath();
        NodeList nodesClasses = (NodeList) xpath.evaluate(&quot;/Plan/featureMember/node()&quot;, document, XPathConstants.NODESET);

        for (int i = 0; i &lt; nodesClasses.getLength(); i++) {
           // System.out.println(nodesClasses.item(i).getNodeName());
            String rawXPath = String.format(&quot;/Plan/featureMember/%s/node()&quot;, nodesClasses.item(i).getNodeName());
            NodeList nodesDetails = (NodeList) xpath.evaluate(rawXPath, document, XPathConstants.NODESET);
            for (int j = 0; j &lt; nodesDetails.item(i).getChildNodes().getLength(); j++) {
                data.put(nodesClasses.item(i).getNodeName(), nodesDetails.item(j).getNodeName());
            }
        }

        return data;

The problem I have an error in this line : NodeList nodesDetails = (NodeList) xpath.evaluate(rawXPath, document, XPathConstants.NODESET);

Error :

javax.xml.xpath.XPathExpressionException: javax.xml.transform.TransformerException: A location step was expected following the &#39;/&#39; or &#39;//&#39; token

How can I specify variable in xpath.evaluate ?

EDIT : Here my xml file :

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Plan&gt;
	&lt;featureMember&gt;
		&lt;TestA&gt;
			&lt;Objet&gt;&lt;/Objet&gt;
			&lt;nature&gt;03&lt;/nature&gt;
			&lt;mastery&gt;5&lt;/mastery&gt;
        &lt;/TestA&gt;
		&lt;TestB&gt;
			&lt;Objet&gt;&lt;/Objet&gt;
			&lt;nature&gt;03&lt;/nature&gt;
			&lt;mastery&gt;5&lt;/mastery&gt;
        &lt;/TestB&gt;
		&lt;TestC&gt;
			&lt;Objet&gt;&lt;/Objet&gt;
			&lt;nature&gt;03&lt;/nature&gt;
			&lt;mastery&gt;5&lt;/mastery&gt;	
        &lt;/TestC&gt;
	&lt;/featureMember&gt;
&lt;/Plan&gt;	

答案1

得分: 1

我看不出你出现错误的具体原因,但你正在使用的方法效率较低。同时,这种方法可能存在安全隐患,你需要意识到可能发生注入攻击的可能性。

与其为每个nodeClasses条目构建和编译新的XPath表达式,不如使用带有变量的通用表达式:

"/Plan/featureMember/*[local-name=$className]/node()"

使用变量解析器将变量绑定到一个值:

xpath.setXPathVariableResolver(varName -&gt; {
   if (varName.getLocalPart().equals("className")) {
      return nodesClasses.item(i).getNodeName();
   } else {
      return "";
   }
}
英文:

I can't see exactly why you're hitting the error, but the approach you're using is inefficient. It's also potentially insecure - you need to be aware of the possibility of injection attacks.

Rather than constructing and compiling a new XPath expression for every entry in nodeClasses, use a generic expression with a variable:

&quot;/Plan/featureMember/*[local-name=$className]/node()&quot;

using a variable resolver to bind the variable to a value:

xpath.setXPathVariableResolver(varName -&gt; {
   if (varName.getLocalPart().equals(&quot;className&quot;)) {
      return nodesClasses.item(i).getNodeName();
   } else {
      return &quot;&quot;;
   }
}

huangapple
  • 本文由 发表于 2020年9月12日 06:33:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63855105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定