English 中文(简体)
G. XML 仅指名下的儿童
原标题:Get XML only immediate children elements by name

www.un.org/spanish/ecosoc 我的问题是:。 如果有与父母一方的“大子女”相同的名称的其他要素,我怎么能直接根据具体的母子要素来掌握有关内容。

http://docs.oracle.com/javase/1.4.2/docs/api/org/w3c/dom/ Package-summary.html” 部件和Im 陷入困境。 这里使用:

<notifications>
  <notification>
    <groups>
      <group name="zip-group.zip" zip="true">
        <file location="C:validdirectory" />
        <file location="C:anothervalidfile.doc" />
        <file location="C:validfilehere.txt" />
      </group>
    </groups>
    <file location="C:validfile.txt" />
    <file location="C:validfile.xml" />
    <file location="C:validfile.doc" />
  </notification>
</notifications>

如你所知,你有两个地方可以把<代码><file>要素定位。 无论是群体还是外部群体。 我真的希望它这样做,因为它更加方便用户。

现在,每当我打电话notificationElement.getElementsByTagName(“file”);给我所有的<file> 内容,包括<group>。 我对这些类型的档案进行不同处理,因此这种功能是不可取的。

我设想了两种解决办法:

  1. Get the parent element of the file element and deal with it accordingly (depending on whether it s <notification> or <group>.
  2. Rename the second <file> element to avoid confusion.

这两种解决办法都不是可取的,因为它们只是留下来,只剩下以下内容:<条码><file>中直接涉及儿童的内容<条码>和斜体;

I m open to IMPO comments and questionnaire about the "best” way to do this, but I m really interest in DOM Solutions because that s what the other of this project is used. 感谢。

最佳回答

无论如何,争端解决署解决这一问题的办法实际上很简单,即使它不过于仓促。

When I iterate through the filesNodeList, which is returned when I call notificationElement.getElementsByTagName("file"), I just check whether the parent node s name is "notification". If it isn t then I ignore it because that will be handled by the <group> element. Here s my code solution:

for (int j = 0; j < filesNodeList.getLength(); j++) {
  Element fileElement = (Element) filesNodeList.item(j);
  if (!fileElement.getParentNode().getNodeName().equals("notification")) {
    continue;
  }
  ...
}
问题回答

I realise you found something of a solution to this in May @kentcdodds but I just had a fairly similar problem which I ve now found, I think (perhaps in my usecase, but not in yours), a solution to.

我的XML格式非常简单的例子如下:

<?xml version="1.0" encoding="utf-8"?>
<rels>
    <relationship num="1">
        <relationship num="2">
            <relationship num="2.1"/>
            <relationship num="2.2"/>
        </relationship>
    </relationship>
    <relationship num="1.1"/>
    <relationship num="1.2"/>

</rels>

As you can hopefully see from this snippet, the format I want can have N-levels of nesting for [relationship] nodes, so obviously the problem I had with Node.getChildNodes() was that I was getting all nodes from all levels of the hierarchy, and without any sort of hint as to Node depth.

看看rel=“noreferer”>API for a while ,我注意到实际上还有两种可能使用的方法:-

这两种方法似乎共同提供了获得诺德所有直系后代要素所需的一切。 下面的jsp法典应当对如何执行这一规定给出一个相当基本的想法。 共同财产调查方案。 我现在把这段话推入一个灯塔,但现在没有时间从单独法中形成一个全面的工作版本。

<%@page import="javax.xml.parsers.DocumentBuilderFactory,
                javax.xml.parsers.DocumentBuilder,
                org.w3c.dom.Document,
                org.w3c.dom.NodeList,
                org.w3c.dom.Node,
                org.w3c.dom.Element,
                java.io.File" %><% 
try {

    File fXmlFile = new File(application.getRealPath("/") + "/utils/forms-testbench/dom-test/test.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fXmlFile);
    doc.getDocumentElement().normalize();

    Element docEl = doc.getDocumentElement();       
    Node childNode = docEl.getFirstChild();     
    while( childNode.getNextSibling()!=null ){          
        childNode = childNode.getNextSibling();         
        if (childNode.getNodeType() == Node.ELEMENT_NODE) {         
            Element childElement = (Element) childNode;             
            out.println("NODE num:-" + childElement.getAttribute("num") + "<br/>
" );          
        }       
    }

} catch (Exception e) {
    out.println("ERROR:- " + e.toString() + "<br/>
");
}

%>

该法典将产生以下产出,只显示最初根 no中的儿童直接因素。

NODE num:-1
NODE num:-1.1
NODE num:-1.2

希望能帮助任何人。 最初员额的乘客。

你们可以为此使用XPath,利用两条途径,使其得以不同处理。

查阅<代码><file> nodes direct children of <notification>//notification/file和<group> use/groups/file

这是一个简单的样本:

public class SO10689900 {
    public static void main(String[] args) throws Exception {
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = db.parse(new InputSource(new StringReader("<notifications>
" + 
                "  <notification>
" + 
                "    <groups>
" + 
                "      <group name="zip-group.zip" zip="true">
" + 
                "        <file location="C:\valid\directory\" />
" + 
                "        <file location="C:\this\file\doesn t\exist.grr" />
" + 
                "        <file location="C:\valid\file\here.txt" />
" + 
                "      </group>
" + 
                "    </groups>
" + 
                "    <file location="C:\valid\file.txt" />
" + 
                "    <file location="C:\valid\file.xml" />
" + 
                "    <file location="C:\valid\file.doc" />
" + 
                "  </notification>
" + 
                "</notifications>")));
        XPath xpath = XPathFactory.newInstance().newXPath();
        XPathExpression expr1 = xpath.compile("//notification/file");
        NodeList nodes = (NodeList)expr1.evaluate(doc, XPathConstants.NODESET);
        System.out.println("Files in //notification");
        printFiles(nodes);

        XPathExpression expr2 = xpath.compile("//groups/group/file");
        NodeList nodes2 = (NodeList)expr2.evaluate(doc, XPathConstants.NODESET);
        System.out.println("Files in //groups/group");
        printFiles(nodes2);
    }

    public static void printFiles(NodeList nodes) {
        for (int i = 0; i < nodes.getLength(); ++i) {
            Node file = nodes.item(i);
            System.out.println(file.getAttributes().getNamedItem("location"));
        }
    }
}

它应当产出:

Files in //notification
location="C:validfile.txt"
location="C:validfile.xml"
location="C:validfile.doc"
Files in //groups/group
location="C:validdirectory"
location="C:	hisfiledoesn texist.grr"
location="C:validfilehere.txt"

如果你与OMAP保持距离,

NodeList nodeList = doc.getElementsByTagName("notification")
    .item(0).getChildNodes();

// get the immediate child (1st generation)
for (int i = 0; i < nodeList.getLength(); i++)
    switch (nodeList.item(i).getNodeType()) {
        case Node.ELEMENT_NODE:

            Element element = (Element) nodeList.item(i);
            System.out.println("element name: " + element.getNodeName());
            // check the element name
            if (element.getNodeName().equalsIgnoreCase("file"))
            {

                // do something with you "file" element (child first generation)

                System.out.println("element name: "
                    + element.getNodeName() + " attribute: "
                    + element.getAttribute("location"));

            }
    break;

}

我们的第一个任务是获得“通知”的内容(在这种情况下是第一个――项目(0)-以及所有儿童:

NodeList nodeList = doc.getElementsByTagName("notification")
    .item(0).getChildNodes();

(你能够利用所有要素与所有要素合作)。

每一名“通知”儿童:

for (int i = 0; i < nodeList.getLength(); i++)

1. 您首先掌握其类型,以便了解它是否是一个要素:

switch (nodeList.item(i).getNodeType()) {
    case Node.ELEMENT_NODE:
        //.......
        break;  
}

如果是这样的话,那么你就去找孩子,不是孙子“通知”

并且你可以检查:

if (element.getNodeName().equalsIgnoreCase("file"))
{

    // do something with you "file" element (child first generation)

    System.out.println("element name:"
        + element.getNodeName() + " attribute: "
        + element.getAttribute("location"));

}

并且是:

element name: file
element name:file attribute: C:validfile.txt
element name: file
element name:file attribute: C:validfile.xml
element name: file
element name:file attribute: C:validfile.doc

I had the same problem in one of my projects and wrote a little function which will return a List<Element> containing only the immediate children. Basically it checks for each node returned by getElementsByTagName if it s parentNode is actually the node we are searching childs of:

public static List<Element> getDirectChildsByTag(Element el, String sTagName) {
        NodeList allChilds = el.getElementsByTagName(sTagName);
        List<Element> res = new ArrayList<>();

        for (int i = 0; i < allChilds.getLength(); i++) {
            if (allChilds.item(i).getParentNode().equals(el))
                res.add((Element) allChilds.item(i));
        }

        return res;
    }

The accepted answer by kentcdodds will return wrong results (e.g. grandchilds) if there is a childnode called "notification" - e.g. returning grandchilds when the element "group" would have the name "notification". I was facing that setup in my project, which is why I came up with my function.

我写了这一功能,使帽子在最高一级获得价值。

public static String getValue(Element item, String tagToGet, String parentTagName) {
    NodeList n = item.getElementsByTagName(tagToGet);
    Node nodeToGet = null;
    for (int i = 0; i<n.getLength(); i++) {
        if (n.item(i).getParentNode().getNodeName().equalsIgnoreCase(parentTagName)) {
            nodeToGet = n.item(i);
        }
    }
    return getElementValue(nodeToGet);
}

public final static String getElementValue(Node elem) {
    Node child;
    if (elem != null) {
        if (elem.hasChildNodes()) {
            for (child = elem.getFirstChild(); child != null; child = child
                    .getNextSibling()) {
                if (child.getNodeType() == Node.TEXT_NODE) {
                    return child.getNodeValue();
                }
            }
        }
    }
    return "";
}

我遇到了一个相关的问题,即尽管所有“档案”节点的处理方式都相似,但我需要处理眼前的儿童节点。 就我的解决办法而言,我比较了Element 母子的 no子和正在处理中的 no子,以确定其是否立即是儿童。

NodeList fileNodes = parentNode.getElementsByTagName("file");
for(int i = 0; i < fileNodes.getLength(); i++){
            if(parentNode.equals(fileNodes.item(i).getParentNode())){
                if (fileNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {

                    //process the child node...
                }
            }
        }

LIN LIN

For Each child As XmlElement In From cn As XmlNode In xe.ChildNodes Where cn.Name = "file"
    ...
Next

我最后在科特林设立了延期职能,以完成这项工作。

fun Element.childrenWithTagName(name: String): List<Node> = childNodes
    .asList()
    .filter { it.nodeName == name }

打电话者可使用:

val meta = target.newChildElement("meta-coverage")
source.childrenWithTagName("counter").forEach {
    meta.copyElementWithAttributes(it)
}

作为清单执行:


fun NodeList.asList(): List<Node> = InternalNodeList(this)

private class InternalNodeList(
    private val list: NodeList,
    override val size: Int = list.length
) : RandomAccess, AbstractList<Node>() {
    override fun get(index: Int): Node = list.item(index)
}





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签