【问题标题】:How do I remove all selected nodes from an XPath?如何从 XPath 中删除所有选定的节点?
【发布时间】:2011-09-06 10:08:42
【问题描述】:

我使用以下 xml 和代码在 Java 中运行 XPath:

<?xml version="1.0" encoding="UTF-8"?>
<list>
    <member name="James">
        <friendlist>
            <friend>0001</friend>
            <friend>0002</friend>
            <friend>0003</friend>
        </friendlist>
    </member>
    <member name="Jamie">
        <friendlist>
            <friend>0003</friend>
            <friend>0002</friend>
            <friend>0001</friend>
        </friendlist>
    </member>
    <member name="Katie">
        <friendlist>
            <friend>0001</friend>
            <friend>0003</friend>
            <friend>0004</friend>
        </friendlist>
    </member>
</list>

代码:

try {
    XPath xpath = XPathFactory.newInstance().newXPath();
    XPathExpression pathExpr = xpath.compile("/list/member/friendlist/friend[.='0003']");
} catch (XPathExpressionException e) {

当然这之后还有更多代码,但我没有在这里粘贴,因为它认为它可能会更加混乱。

但我的想法是我希望从所有成员的好友列表节点中选择 ID 为 0003 的所有好友节点,然后将其从 XML 文件中删除。 XPath 通过选择所有值=0003 的“朋友”节点来工作。我知道我可以使用 XML Document 对象的 removeChild() 方法。但问题是我如何直接删除所有这些,而不需要从其父级开始遍历层级循环? removeChild() 方法需要我知道它的父母的父母的父母。

谢谢!

更新: 这就是我使用 XPath 的方式:

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression pathExpr = null;
try {
    pathExpr = xpath.compile("/list/member/friendlist/friend[.='0003']");
} catch (XPathExpressionException e) {
    e.printStackTrace();
}
NodeList list = null;
try {
    list = (NodeList) pathExpr.evaluate(xmlDoc, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
    e.printStackTrace();
}

xmlDoc 是一个已解析 XML 文件的 XML 文档对象。 XML 工作正常。只是 XML 没有返回引用,而是一个全新的节点列表,这使我无法参考其原始 xml 文档进行修改。

【问题讨论】:

  • xmlDoc 是 org.w3c.Document 对象吗?
  • 是的,xmlDoc 是一个常规的 org.w3c.Document 对象。
  • 您使用的是 jdk 的 xpath 支持,还是其他第三方库? (例如,您的 XPath 实例的实际类名是什么)
  • 我正在使用来自 JDK 的 xpath。我从不使用任何第三方库。我的 XPath 实例的类路径是 javax.xml.xpath.XPath。
  • 不,不是公共 api,我的意思是 actual 实现类(例如xpath.getClass()

标签: java xml xpath


【解决方案1】:

对于返回的 NodeList 中的每个节点:

n.getParentNode().removeChild(n);

【讨论】:

  • 显然,当我执行 n.getParentNode() 时,它返回一个空的 xml。所以当我执行 n.getParentNode().removeChild(n) 时,我会得到一个 nullpointerexception,因为由于某种原因 getParentNode() 返回一个 null 值。 Xpath 似乎返回了另一组 xml 数据,并且没有引用实际的 xml 文档对象。我需要做些什么来完成这项工作吗?谢谢!
  • @xEnOn - 好吧,由于您没有包含任何相关代码,因此很难提供更多建议......
  • 在大多数从 XML 文档对象执行标准过程的常用 xml 代码中,n.getParentNode().removeChild(n) 方法可以完美运行。只有当我通过 XPath 从 XPathFactory 查询节点列表时,工厂类似乎返回了我查询过的节点的新节点列表,而不是对原始 XML 文档对象中原始节点的引用。所以我在使用n.getParentNode()的时候,返回的数据不正确,removeChild不能正常工作。
  • @xEnOn - 你怎么称呼 xpath
  • 我已经更新了我如何在帖子底部调用 xpath 的问题。感谢您的帮助。
【解决方案2】:

看看XUpdate。它不漂亮,但它有效。

【讨论】:

    【解决方案3】:

    我不明白为什么返回的节点列表的节点为 parentNode() 返回 null。

    但您可以先尝试使用以下 XPath 表达式选择要删除的节点的所有父节点:

    "/list/member/friendlist[friend[.='0003']]"
    

    或等价物,

    "/list/member/friendlist[friend = '0003']]"
    

    然后遍历生成的节点列表,并在每个节点的上下文中,查询匹配 XPath 表达式的节点

    "friend[.='0003']"
    

    这将为您提供一个父节点和一个子节点以用于removeChild()

    【讨论】:

    • 谢谢!我也试过你的方法,它也有效!聪明的把戏!
    猜你喜欢
    • 2012-11-29
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多