2016-11-16 11 views
0

비정상적인 요청이 있습니다. 내가 예를 찾습니다 xml 파일을 생성해야합니다. 나는 JDOM API를 사용하여 XML을 생성하고 자바를 사용하여 xml 요소에 반복적 인 네임 스페이스 포함

<?xml version="1.0" encoding="UTF-8"?> 
<pk:DeviceInfo xmlns:pk="urn:ietf:params:xml:ns:kyp:pk" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <pk:Manufacturer xmlns:pk="urn:ietf:params:xml:ns:kyp:pk" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     ABC 
     </pk:Manufacturer> 
     <pk:SerialNo>123456</pk:SerialNo> 
     <pk:Model>Model1</pk:Model> 
     <pk:IssueNo>1</pk:IssueNo> 
</pk:DeviceInfo> 

아래 같은. 문제는 pk : Manufacturer 요소에 대한 네임 스페이스를 선언하더라도 jdom은 루트 요소에 이미 선언되어 있기 때문에 거기에 추가하지 않는다는 것입니다. 하지만이 파일을이 형식으로 있어야하는 다른 서버로 보내야하기 때문에 자식 요소에서도 네임 스페이스 선언을 반복해야합니다.
jdom doen't는 이것을 허용하므로 jml로 먼저 xml을 만들고 elmt.setAttributeNS()를 사용하여 자식 요소에 네임 스페이스를 포함하기 위해 DOM 파서로 XML을 업데이트하려고 시도했지만 불행히도 이것은 보이지 않는다 일하다. 이전에이 문제에 직면 한 사람이 있습니까?

+1

"XML을이 형식으로해야하는 다른 서버로이 파일을 보내야합니다."다른 서버가 상위 요소에 대한 네임 스페이스 선언이 오버라이드되지 않으면 자손 범위에 있음을 분명히 나타내는 네임 스페이스가있는 XML을 이해할 수 없음을 나타냅니다. 따라서 내부 네임 스페이스 선언은 중복되며 DOM 트리의 대부분의 serializer는이를 작성하지 않습니다. 일반적으로 XML을 받아들이거나 상대방 네임 스페이스 선언을 작성하도록 사용자 고유의 serializer를 작성하기 위해 상대방을 수정하는 쉬운 방법은 없습니다. –

+0

XMLOutputter의 "프로세서"에 대한 사용자 정의를 구현하고 해당 사용자 정의를 위해 문서의 모든 관련 레벨을 네임 스페이스로 인쇄 할 수 있습니다. 그것은 최후의 수단이 될 것입니다. XML 구문 분석기를 사용하여 내용을 구문 분석하는 시스템을 다른 쪽에서 수정하는 것이 더 낫습니다. (지금 당연히 일치하는 파서는 아닙니다.) 자신 만의 프로세서를 구현하고 다음 행을 변경하십시오. https://github.com/hunterhacker/jdom/blob/master/core/src/java/org/jdom2/output/support/AbstractXMLOutputProcessor.java#L805 – rolfl

+0

You 각 레벨에서 다른 네임 스페이스 URI를 사용하여 XML을 생성 한 다음 더미 URI를 실제 URI로 바꿀 수있는 약간의 사후 처리 (비 XML 도구 사용)를 수행 할 수 있습니다. (그러나 다른 사람들은 애플리케이션이 XML을 올바르게 읽거나 쓰지 않는다면 시스템의 다른 부분으로 부족한 부분을 퍼뜨리는 것을 원하지 않는다. 깨진 애플리케이션을 고쳐야한다.) –

답변

1
당신은 당신이 시도하는 DOM 코드 우리를 표시하지 않은하지만 오라클 자바 1.8

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(true); 

    DocumentBuilder db = dbf.newDocumentBuilder(); 

    Document doc = db.newDocument(); 

    String ns1 = "http://example.com/ns1"; 
    String ns2 = "http://example.com/ns2"; 

    Element root = doc.createElementNS(ns1, "pf1:root"); 
    root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf2", ns2); 

    doc.appendChild(root); 

    Element foo = doc.createElementNS(ns1, "pf1:foo"); 
    foo.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf1", ns1); 
    foo.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:pf2", ns2); 
    root.appendChild(foo); 

    DOMImplementationLS domImp = (DOMImplementationLS)doc.getImplementation(); 

    LSSerializer ser = domImp.createLSSerializer(); 

    System.out.println(ser.writeToString(doc)); 

을 테스트 할 때 출력 따라서 아이에 명시 적으로 만든 네임 스페이스 속성 선언

<pf1:root xmlns:pf1="http://example.com/ns1" xmlns:pf2="http://example.com/ns2"><pf1:foo xmlns:pf1="http://example.com/ns1" xmlns:pf2="http://example.com/ns2"/></pf1:root> 

입니다

직렬화됩니다. W3C DOM을위한 방법이어야합니다. 명시 적으로 필요한 요소에 네임 스페이스 선언을 만들고 LSSerializer를 사용하여 트리를 작성하십시오.

+0

완벽한! LSSerializer는 나를 위해 트릭을했습니다. 이전에는 javax.xml.transform.Transformer를 사용하여 dom 소스를 xml로 변환했습니다. 이제 LSSerializer는 xml을 반복적 인 네임 스페이스로 작성할 수 있습니다. –