2014-03-03 1 views
0

로컬 소켓을 통해 클라이언트의 소프트웨어와 통신하는 시뮬레이터를 작성 중입니다. 통신 언어는 XML입니다. 들어오는 XML 문자열을 DocumentBuilder 인터페이스를 통해 Document로 파싱하는 코드를 작성했습니다.XML에서 CDATA를 파싱하여 Java 편집 가능

CDATA에 문제가 발생했습니다 (이전에는 본 적이 없었 음). 기본적으로 CDATA 태그 내의 필드에 액세스하여 변경해야합니다. '템플릿'XML 문서를로드 (메시지에 응답)하고 응답 내의 첫 번째 메시지에서받은 값을 사용합니다. 변경해야 할 필드 중 일부는이 CDATA 태그에 있습니다 (아래에서 의미하는 바를 명확히하십시오).

public static String getOutputMessage(String input) throws Exception{ 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    Document inputDoc, outputDoc; 
    Element messageElement = (Element)inputDoc.getElementsByTagName("TRANS").item(0); 
    messageType = messageElement.getAttribute("name"); 
    if (messageType.equals("processTransaction")){ 
     outputDoc = db.parse(path+"processTransaction\\posPrintReceipt.xml"); 
     outputDoc = changeContent(outputDoc, "PAN_NUMBER", transaction.getPan_number()); 
     outputDoc = changeContent(outputDoc, "TOKEN", transaction.getToken()); 
     outputDoc = changeContent(outputDoc, "TOTAL_AMOUNT", transaction.getTotal_amount()); 
     outputDoc = changeContent(outputDoc, "TRANSACTION_TIME", transaction.getTransaction_time()); 
     outputDoc = changeContent(outputDoc, "TRANSACTION_DATE", transaction.getTransaction_date()); 
    } 
} 

private static Document changeContent(Document doc,String tag,String value) { 
    System.out.println("Changing: ["+tag+" : "+value+"]"); 
    NodeList nodes=doc.getElementsByTagName(tag); 
    Node node = nodes.item(0); 
    Node parent=node.getParentNode(); 
    node.setTextContent(value); 
    System.out.println(doc.getElementsByTagName(tag).item(0) + " " + node.getTextContent()); 
    parent.replaceChild(node, doc.getElementsByTagName(tag).item(0)); 
    return doc; 
} 

정상 요소 일 상기 기능하지만, 이하는 I 읽고 일부 값 등

<RLSOLVE_MSG version="5.0"> 
<MESSAGE> 
    <SOURCE_ID>DP01</SOURCE_ID> 
    <TRANS_NUM>000001</TRANS_NUM> 
</MESSAGE> 
<POI_MSG type="interaction"> 
    <INTERACTION name="posPrintReceipt"> 
     <RECEIPT type="merchant" format="xml"> 
      <![CDATA[<RECEIPT> 
    <AUTH_CODE>06130</AUTH_CODE> 
    <CARD_SCHEME>VISA</CARD_SCHEME> 
    <CURRENCY_CODE>GBP</CURRENCY_CODE> 
    <CUSTOMER_PRESENCE>internet</CUSTOMER_PRESENCE> 
    <FINAL_AMOUNT>1.00</FINAL_AMOUNT> 
    <MERCHANT_NUMBER>8888888</MERCHANT_NUMBER> 
    <PAN_NUMBER>454420******0382</PAN_NUMBER> 
    <PAN_EXPIRY>12/15</PAN_EXPIRY> 
    <TERMINAL_ID>04176421</TERMINAL_ID> 
    <TOKEN>454420bbbbbkqrm0382</TOKEN> 
    <TOTAL_AMOUNT>1.00</TOTAL_AMOUNT> 
    <TRANSACTION_DATA_SOURCE>keyed</TRANSACTION_DATA_SOURCE> 
    <TRANSACTION_DATE>14/02/2014</TRANSACTION_DATE> 
    <TRANSACTION_NUMBER>000001</TRANSACTION_NUMBER> 
    <TRANSACTION_RESPONSE>06130</TRANSACTION_RESPONSE> 
    <TRANSACTION_TIME>17:13:17</TRANSACTION_TIME> 
    <TRANSACTION_TYPE>purchase</TRANSACTION_TYPE> 
    <VERIFICATION_METHOD>unknown</VERIFICATION_METHOD> 
    <DUPLICATE>false</DUPLICATE> 
</RECEIPT>]]> 
     </RECEIPT> 
    </INTERACTION> 
</POI_MSG> 
을 변경해야하는 예시적인 XML 메시지 인

+0

http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/CDATASection.html –

답변

0

CDATA 임의 포함하는 부호화 메커니즘 XML 파일 내의 데이터. XML을 Document 인스턴스로로드 할 때 CDATA 내의 모든 내용이 단일 문자열로 구문 분석됩니다. CDATA의 내용에 DOM 문서로 액세스해야하는 경우 문자열 내용에서 두 번째 Document 객체를 인스턴스화하고 변경 한 다음 다시 문자열로 직렬화하고 문자열을 CDATA에 다시 넣어야합니다. 원본 문서.

+0

안녕하세요, 귀하의 회신에 감사드립니다. 나는 이것이 최선의 방법이 될 것이라는 데 동의한다. (안타깝게도 외부 클라이언트로부터받은 메시지의 형식을 바꿀 수 없다.) CDATA 정보를 어떻게 추출 하시겠습니까? CharacterData.getData() 함수를 사용 하겠지만 XML의 모든 태그를 검사하지 않고 CDATA 태그를 찾는 방법을 찾지 못하는 것 같습니다 (모든 노드에서 루핑을 통해). 즉 doc.getElementByTagName ("CDATA") 사용이 작동하지 않는 것 같습니다. – user3347799

+0

CDATA는 태그가 아니므로 그런 식으로는 찾을 수 없습니다. 포함하는 태그의 이름을 알아야합니다. 귀하의 예제에서'format = "xml"'속성이 XML을 포함하는 태그를 찾을 수있게 해줄 것입니다. 이것은 여러분이 찾고있는 것입니다. XPath는'// * [@ format = 'xml']' –

+0

안녕하세요, 그래서이 문서에서 CDATA를 찾아 추출하는 함수를 작성했습니다. "RECEIPT"요소를 성공적으로 검색하고 자식이 CDATA임을 인식하지만 문자 데이터에서 cd.getData()를 시도하면 다음을 얻습니다. [ , \t, \t, \t, \t] (\ n \ t \ t \ t \ t로 인식) 왜 그런가? – user3347799

0

필자는 CDATA 섹션이 XML의 다른 일반 요소로 파싱 될 것이라고 생각하지 않습니다. CDATA 섹션은 순전히 구문 확인을 이스케이프 처리합니다. 내 제안은 CDATA 섹션에서 데이터를 나타내는 요소를 사용하는 것입니다. 그래도 CDATA 섹션을 사용하려면 섹션을 문자열로 구문 분석 한 다음 데이터를 문서로로드해야합니다.