‘XML 그냥 toString() 하던지 toXMLString() 하면 String 만들어주잖아?’ 라고 말이죠.
물론 XML의 toXMLString() 메소드를 호출하면 String 으로 만들어줍니다. 다만, 이게 개행문자(\n)가 포함되어있어서 문제가 됩니다. (개행문자 같은 metasequences는 이 곳을 참고하세요.)
- var sourceXML:XML = <root>
- <items>
- <item classtype=‘UIComponent’ id=‘myUIComponent’ x=’10’ y=’10’ width=’20’ height=’20’/>
- <item classtype=‘Canvas’ id=‘myCanvas’ x=’20’ y=’40’ width=’30’ height=’30’/>
- <item classtype=‘Panel’ id=‘myPanel’ x=’30’ y=’60’ width=’40’ height=’40’/>
- </items>
- </root>;
- var xmlString:String = sourceXML.toXMLString();
- var targetXML:XML = new XML(xmlString);
위와 같은 코드가 있다고 할 때에 sourceXML.toXMLString() 해서 나온 String을 담고 있는 xmlString 에는 무엇이 들어있을까요?
XML을 String으로 만들었으니 아래와 같이 있겠죠?
<root><items><item classtype=”UIComponent” id=”myUIComponent” x=”10″ y=”10″ width=”20″ height=”20″/><item classtype=”Canvas” id=”myCanvas” x=”20″ y=”40″ width=”30″ height=”30″/><item classtype=”Panel” id=”myPanel” x=”30″ y=”60″ width=”40″ height=”40″/></items></root>
실제로 위와 같이 들어있을까요? 아닙니다. 실제 아래와 같이 개행문자가 포함된 아래의 String이 들어있습니다.
<root>\n <items>\n <item classtype=”UIComponent” id=”myUIComponent” x=”10″ y=”10″ width=”20″ height=”20″/>\n <item classtype=”Canvas” id=”myCanvas” x=”20″ y=”40″ width=”30″ height=”30″/>\n <item classtype=”Panel” id=”myPanel” x=”30″ y=”60″ width=”40″ height=”40″/>\n </items>\n</root>
XML을 toXMLString()으로 String으로 만들면 계층구조에 맞게 개행문자를 넣어서 String을 만들어줍니다. 그래서 해당 String을 trace() 를 해보면 아래와 같이 콘솔에 XML의 계층구조로 보이게 됩니다. ( toString() 을 사용해도 마찬가지 입니다.)
Flex에서 위의 xmlString 을 다시 XML 로 만들더라도 아무런 문제는 없습니다. (targetXML 에 sourceXML과 같은 XML 이 아무런 문제없이 담깁니다.) 하지만, 이렇게 변환된 String을 서버에서 사용시 문제가 생깁니다. 저는 HTTPService에서 자바 서블릿(Servlet)을 호출하여 위와 같은 XML 데이터(파라미터 이름:mydata)를 보내어서 일련의 작업을 하려고 했습니다. 아래는 해당 값을 받는 서블릿입니다.
- import java.io.IOException;
- import java.io.StringReader;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import org.w3c.dom.Document;
- import org.xml.sax.InputSource;
- public class myServlet extends HttpServlet
- {
- protected void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException
- {
- doPost(request, response);
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException
- {
- String requestXML = request.getParameter(“mydata”); // XML데이터를 받음.
- Document document = convertDocument(requestXML);// Document로 변환함
- // something….
- }
- public Document convertDocument(String requestXML)
- {
- DocumentBuilderFactory factory = null;
- DocumentBuilder builder = null;
- Document document = null;
- try
- {
- // String을 XML 형태로 변환하자
- factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(true);
- builder = factory.newDocumentBuilder();
- document = builder.parse(new InputSource(new StringReader(requestXML)));
- }
- catch(Exception ex)
- {
- // 에러를 출력
- }
- return document;
- }
- }
request.getParameter(“mydata”); 라고 구현하여서 실제 Flex 에서 보낸 XML 데이터를 String에 담았습니다. 그러나 이때 이 정보를 DOM 파서를 이용하여 실제 XML로 처리하고 싶어 Document 객체를 만들어 쓰는 과정에서 문제가 생깁니다. 각 노드들의 정보를 가지고 올때 이상한 문자 들어있지 않나…;; Flex에서는 XML을 보냈으나 실제 서블릿에서 받는 데이터는 개행문자가 담겨있는 위와 같은 String 이기 때문입니다.
이러한 문제때문에 Flex에서 XML 을 String으로 만들때 개행문자를 없애는 것에 대해 고민을 했습니다.
답이 안나오더군요. -_-; 어떻게 해야되는지도 모르겠고요. 해서 toXMLString() 대신에 사용할 정적 메소드를 하나 만들었습니다.
- package
- {
- public class Utils
- {
- public static function toXMLString(value:XML):String
- {
- var result:String = value.toXMLString(); //String으로 변환
- var pattern:RegExp = /\n */g; //개행문자를 없앨 정규식
- result = result.replace(pattern, “”); //개행문자를 없엔다
- return result;
- }
- }
- }
(남남남 님께서 덧글로 남겨주신 g 플래그를 사용함)
수정 전 소스 닫기
- package
- {
- public class Utils
- {
- public static function toXMLString(value:XML):String
- {
- var result:String = value.toXMLString(); //String으로 변환
- var counter:int = result.split(“\n”).length; //개행문자의 갯수를 알아온다
- var pattern:RegExp = /> *\n *</; //개행문자를 없앨 정규식
- for(var i:int=0; i<counter; i++)
- {
- result = result.replace(pattern, “><“); //개행문자를 없엔다
- // replaceAll 이 없는 관계로다가…;;
- }
- return result;
- }
- }
- }
수정 전 소스 닫기