2012-02-01 8 views
1

빈 요소와 빈 요소가 있지만 출력 특성을 가진 출력 XML이 있습니다.Java에서 빈 XML 요소를 제거하십시오.

일부 문제를 해결하는 데 도움이되는 구형 게시물을 확인했습니다.

나는 다음과 같은 XSLT 솔루션

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="@*|node()"> 
    <xsl:if test=". != '' or ./@* != ''"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:if> </xsl:template> </xsl:stylesheet> 

을 사용하지만, 문제는 또한

<CurrencyList> 
<Currency code="EURO"/> 
<Currency code="USD"/> 
</CurrencyList> 

사람과 같은 속성을 가진 자식 요소 방법이 문제를 해결하는 아이디어가를 가진 요소를 제거입니까?

많은 감사

+0

xml을 구문 분석하고 각 요소에서 하위 및 특성을 확인하는 것이 옵션이 아닙니다. – tartak

+0

@CatalinCiobanu 그렇습니다. – achraf

+0

일 수 있습니다. List 과 같은 요소를 얻을 수 있었고 크기를 묻습니다. 그러나 우리 동료 인 Joop Eggen은 더 나은 (훨씬 더 좋은) 솔루션 -> 재귀를 제안합니다! – tartak

답변

1

그것은 빈 디렉토리를 삭제 같다 : 당신은 깊이 우선 재귀 산책을 할 필요가 : 모든 하위 디렉토리가 삭제 된 경우, 다음 하나는 현재 디렉토리를 삭제 고려할 수 있습니다.

결과적으로 삭제는 Java에서 재귀를 사용하여 수행하는 것이 가장 좋습니다. 장점은 사본이 필요 없다는 것입니다.


코드 요청에

의 XML API를 사용하여 작업하는 매우 단편적인 한, 일부 검증되지 않은 코드 :

import java.io.*; 
import java.util.*; 
import javax.xml.parsers.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import org.w3c.dom.*; 
import org.xml.sax.SAXException; 

public class XmlCleanup { 

    public static void main(String[] args) { 
     if (args.length == 0) { 
      args = new String[] { "/home/joop/Labortablo/test1.xml" }; 
     } 
     new XmlCleanup().process(args[0]); 
    } 

    public void process(String xmlPath) { 
     try { 
      // Read XML document: 
      DocumentBuilder builder = 
        DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
      Document doc = builder.parse(new File(xmlPath)); 

      removeEmptyChildElements(doc.getDocumentElement()); 

      // Write XML document back: 
      TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
      Transformer transformer = transformerFactory.newTransformer(); 
      DOMSource source = new DOMSource(doc); 
      StreamResult result = new StreamResult(new File(xmlPath 
        .replaceFirst("\\.xml$", "") + "-clean.xml")); 
      transformer.transform(source, result); 
     } catch (TransformerException ex) { 
      Logger.getLogger(XmlCleanup.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (SAXException ex) { 
      Logger.getLogger(XmlCleanup.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IOException ex) { 
      Logger.getLogger(XmlCleanup.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (ParserConfigurationException ex) { 
      Logger.getLogger(XmlCleanup.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    private void removeEmptyChildElements(Element parentElement) { 
     List<Element> toRemove = new LinkedList<Element>(); 

     NodeList children = parentElement.getChildNodes(); 
     int childrenCount = children.getLength(); 
     for (int i = 0; i < childrenCount; ++i) { 
      Node child = children.item(i); 
      if (child.getNodeType() == Node.ELEMENT_NODE) { 
       Element childElement = (Element) child; 
       removeEmptyChildElements(childElement); 
       if (elementIsRedundant(childElement)) { 
        toRemove.add(childElement); 
       } 
      } 
     } 

     for (Element childElement: toRemove) { 
      parentElement.removeChild(childElement); 
     } 
     parentElement.normalize(); 
    } 

    private boolean elementIsRedundant(Element element) { 
     if (element.hasAttributes()) 
      return false; 
     if (!element.hasChildNodes()) 
      return true; 
     NodeList children = element.getChildNodes(); 
     int childrenCount = children.getLength(); 
     for (int i = 0; i < childrenCount; ++i) { 
      Node child = children.item(i); 
      String value = child.getNodeValue(); 
      if (value != null && !value.matches("\\s*")) { 
       return false; // Found non-whitespace text 
      } 
     } 
     return true; 
    } 
} 

그것은 그래서 당신은 XSLT 변환을 사용할 수 있습니다 java.xml.transform를 사용 너무; 조금 더 간단하면 javax.xml.stream.XMLOutputFactory을 사용하는 것입니다.

+0

죄송합니다. Java에서 XML 처리의 초보자입니다. 어떻게 처리 할 수 ​​있습니까? – achraf

+0

여기를 살펴보면 시작 지점 일 수 있습니다. http://stackoverflow.com/questions/47026/recursive-function-for-an-xml-file-hierarchial-data – tartak

0

나는 당신이 정체성 변환으로 시작하여 올바른 길에 있다고 생각합니다. ID 템플릿을있는 그대로 유지 한 다음 빈 요소를 무시하는보다 구체적인 템플릿을 추가하는 것이 좋습니다.

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
</xsl:template> 

호출은 'normalize-space`는이 템플릿 붕괴 보통 들여 쓰기에 사용되는 모든 연속적인 공백을합니다. 다음으로 일치 항목의 두 번째 부분은 속성 자체가 있거나 속성이있는 하위 항목이있는 모든 요소를 ​​제외합니다. 디버깅 목적을 위해 필자는 요소가 제거 될 때마다 템플릿에 출력에 주석을 작성하게했습니다.

<xsl:template match="*[normalize-space(.) = '' and not(descendant-or-self::*/@*)]"> 
    <xsl:comment><xsl:value-of select="name(.)" /></xsl:comment> 
</xsl:template> 
관련 문제