【问题标题】:Retrieve element with Jdom / XPath and "使用 Jdom / XPath 和“检索元素”
【发布时间】:2018-11-20 09:20:56
【问题描述】:

我正在开发具有此类 xml 文件 (document.xml) 的应用程序:

<root>
    <subRoot myAttribute="CN=Ok">
        Ok
    </subRoot>
    <subRoot myAttribute="CN=&quot;Problem&quot;">
        Problem
    </subRoot>    
</root>

我需要使用 XPath 表达式检索 Element。我无法检索第二个元素,我需要使用myAttribute 的值来选择它。这是由于&amp;quot; 字符...

这是一个测试类。第二个断言抛出 AssertionError 因为对象为空。

import static org.junit.Assert.assertNotNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import org.apache.commons.io.IOUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import org.junit.Test;

public class XPathTest {

    @Test
    public void quotesXpath() throws JDOMException, IOException {
        Document document = getDocumentFromContent(getClasspathResource("document.xml"));

        String okXPath = "/root/subRoot[@myAttribute=\"CN=Ok\"]";
        assertNotNull(getElement(document, okXPath)); // Ok ...

        String problemXPath = "/root/subRoot[@myAttribute=\"CN=&quot;Problem&quot;\"]";
        assertNotNull(getElement(document, problemXPath)); // Why null ?
    }

    public String getClasspathResource(String filePath) throws IOException {
        try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) {
            return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        }
    }

    public static Document getDocumentFromContent(String content) throws IOException, JDOMException {
        try (InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) {
            SAXBuilder builder = new SAXBuilder();
            return builder.build(is);
        }
    }

    public Element getElement(Document document, String xpathExpression) throws JDOMException {
        XPath xpath = XPath.newInstance(xpathExpression);
        return (Element) xpath.selectSingleNode(document);
    }
}

应用程序正在使用 Jdom 1.1.3

<dependency>
   <groupId>org.jdom</groupId>
   <artifactId>jdom</artifactId>
   <version>1.1.3</version>
</dependency>

如何更改我的 xpath 表达式以返回第二个元素?这个版本的 Jdom 可以吗?

感谢您的帮助!

【问题讨论】:

  • 尝试解决方法/root/subRoot[starts-with(@myAttribute, \"CN=\") and contains(@myAttribute, \"Problem\")]
  • 谢谢@Andersson。我喜欢这个想法,它可能适用于我的示例。但我认为我已经简化了太多。我最终可能会选择另一个所需的元素。我真的需要选择像“CN=Problem”这样的东西,而不是“CN=Something, ... Problem”。
  • 好的。另一个解决方法是/root/subRoot[contains(substring-after(@myAttribute, \"CN=\"), \"Problem\") and string-length(@myAttribute)=12]。这应该匹配所需的节点。例外情况是CN= Problem "CN=&amp;Problem&amp;"CN= Problems" 等......所以只有两个字符不同
  • 由于属性值在现实生活场景中更复杂,我认为@forty-2 的答案更简单。感谢您的帮助。

标签: java xpath jdom


【解决方案1】:

试试这个表达式:

    String problemXPath = "/root/subRoot[@myAttribute='CN=\"Problem\"']";

首先,当解析文档时,实体&amp;quot;被替换为"字符,所以应该直接在XPath表达式中使用。

其次,在 XPath 中,您可以对字符串常量使用单引号或双引号,如果您有包含引号的字符串,这会很方便。

【讨论】:

    猜你喜欢
    • 2012-09-14
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多