내 질문은: 부모 요소의 <손자>와 같은 이름을 가진 다른 요소가 있을 때 특정 부모 요소 바로 아래에 있는 요소를 어떻게 가져올 수 있나요?
Java DOM 라이브러리를 사용하여 XML 요소를 구문 분석하고 있는데 문제가 발생하고 있습니다. 다음은 제가 사용하고 있는 XML의 일부(일부)입니다:
<notifications>
<notification>
<groups>
<group name="zip-group.zip" zip="true">
<file location="C:\valid\directory\" />
<file location="C:\another\valid\file.doc" />
<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>
보시다시피 파일
요소를 배치할 수 있는 위치에는 두 가지가 있습니다. 그룹 내부 또는 그룹 외부입니다. 저는 이 방식으로 구조화하는 것이 더 사용자 친화적이기 때문입니다.
이제 notificationElement.getElementsByTagName("file");
을 호출할 때마다 그룹
요소 아래에 있는 요소를 포함하여 모든 파일
요소를 제공합니다. 저는 이러한 종류의 파일을 각각 다르게 처리하므로 이 기능은 바람직하지 않습니다.
두 가지 해결책을 생각해 봤습니다:
알림
또는 그룹
인지에 따라 다름).<file
요소의 이름을 바꿉니다.이 두 가지 방법 중 어느 것도 <notification
요소의 직접 자식인 <file
요소만 가져오는 것만큼 바람직한 해결책은 없습니다.
이 작업을 수행하는 가장 좋은 방법에 대한 IMPO의 의견과 답변에 열려 있지만이 프로젝트의 나머지 부분에서 사용하고 있기 때문에 DOM 솔루션에 정말 관심이 있습니다. 고마워요.
내가 이 일을 해법을 찾은 것은 지난 5월 깨닫게 @kentcdodds 인도하심이라만일 상당히 유사한 문제가 있는 것으로, 이제 그냥 I& # 39, ve 생쥐라. (아마도 내 우스카스 있지만, 당신 애두요), 해법을.
예를 들어 매우 상투적이고 내 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>
I want, 형식을 통해 알 수 있듯이 이 스니핏을 용이하게 할 수 있는 것은 분명 문제가 있다, 그래서 내가 갖고 중첩할 n 수준 장치당 [릴레이션십] 노드입니다 노엘가제차일드노스 () 는 모든 레벨에서 노드입니다 계층 없이 모두 가져오는 거라고 어떤 종류의 힌트 '으로 노드입니다 심도입니다.
이 두 가지 방법이 제공하는 데 필요한 모든 것, 함께 있던 모든 즉시인지 하위 요소를 노드입니다. 다음 코드 줘야 할 기본적인 개념은 상당히 jsp 구현 방법 이. 지금은 JSP. 하지만, 이제 이 붙여넣습니다 i& # 39 m, t # 39 시간은 아직 큰 콩 didn& 완전히 다른 버전의 apc® 자신의 코드를 만들 수 있습니다.
<%@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/>\n" );
}
}
} catch (Exception e) {
out.println("ERROR:- " + e.toString() + "<br/>\n");
}
%>
이 코드는 다음과 같은 출력물을 직접 보여 줄 것 "이라고 자식 요소로 디렉토리에만 초기 스크립트루트 노드입니다.
NODE num:-1
NODE num:-1.1
NODE num:-1.2
따라서 누군가가 희망을 겁니다. 건배 최초 게시물로의.
[2]: http://docs.oracle.com/javase/1.4.2/docs/api/org/w3c/dom/Node.html # getFirstChild% 28%29 [3]: http://docs.oracle.com/javase/1.4.2/docs/api/org/w3c/dom/Node.html # getNextSibling% 28%29
이를 위해 XPath를 사용하여 두 경로를 가져와서 다르게 처리할 수 있습니다.
파일노드를 가져오려면 ``알림
노드의 직접 자식인 //알림/파일
을 사용하고 /그룹
노드의 자식인 //groups/group/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>\n" +
" <notification>\n" +
" <groups>\n" +
" <group name=\"zip-group.zip\" zip=\"true\">\n" +
" <file location=\"C:\\valid\\directory\\\" />\n" +
" <file location=\"C:\\this\\file\\doesn't\\exist.grr\" />\n" +
" <file location=\"C:\\valid\\file\\here.txt\" />\n" +
" </group>\n" +
" </groups>\n" +
" <file location=\"C:\\valid\\file.txt\" />\n" +
" <file location=\"C:\\valid\\file.xml\" />\n" +
" <file location=\"C:\\valid\\file.doc\" />\n" +
" </notification>\n" +
"</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:\valid\file.txt"
location="C:\valid\file.xml"
location="C:\valid\file.doc"
Files in //groups/group
location="C:\valid\directory\"
location="C:\this\file\doesn't\exist.grr"
location="C:\valid\file\here.txt"
글쎄요, 이 질문에 대한 DOM 솔루션은 너무 우아하지는 않지만 실제로는 매우 간단합니다. notificationElement.getElementsByTagName("file");
을 호출할 때 반환되는 filesNodeList
를 반복할 때 부모 노드의 이름이 알림
인지 확인하고 그렇지 않은 경우 그룹
요소에서 처리하므로 무시합니다. 제 코드 솔루션은 다음과 같습니다:
for (int j = 0; j < filesNodeList.getLength(); j++) {
Element fileElement = (Element) filesNodeList.item(j);
if (!fileElement.getParentNode().getNodeName().equals("notification")) {
continue;
}
...
}
DOM API를 고수하는 경우
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++)
의 모든 자식에 대해 먼저 그 유형을 가져와서 엘리먼트인지 확인합니다:
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:\valid\file.txt
element name: file
element name:file attribute: C:\valid\file.xml
element name: file
element name:file attribute: C:\valid\file.doc
난 내 프로젝트 중 하나로 경식도 동일한 문제가 좀 있는 한, ',' List< 및 작성했습니까 함수은 반환되므로 Element> redboot*용 즉시인지 만 명의 자녀를 두고 있다. 기본적으로 각 노드에 대한 검사를 통해 'it' s # 39, 실제로 노드입니다 발렌티노데 it& 반환되었습니다 게테레멘츠비타냐메 경우 우리는 검색: 차일즈 다음과 같다.
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;
}
이 경우 (예를 들면 손자) 에 의해 잘못된 결과를 수락됨 오토메이티드 켄트크도데스 반환되므로 힐데노데 " 불렀으매 notification"; 돌아갈 때, 즉 손자 요소점 " group". 있을 이름을 notification" ";). 난 내 프로젝트가 진행되고 있는 상황을 평면가공 내가 왜 내 함수은 지었지.
난 그냥 어디서) 에서 관련 문제를 처리하는 데 필요한 경우에도 즉시 치료를 자식 노드가 모든 " file"; 노드입니다 비슷하다. # 39 의 상위 노드입니다 Element& 비교, 난 내 솔루션을 통해 처리되는 요소는 노드로서 여부를 밝혀내기 위해 즉시 아기 "라고 말했다.
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...
}
}
}
내가 이 기능을 작성했습니까 내려받습니다 노드입니다 의해 값이 타냐메, 최상위 수준으로 제한할 수 있습니다.
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 "";
}