이 변환기는 XML 문서에 대한 Kotlin data class를 씁니다. 모든 XML 변환기가 공유하는 규칙으로 XML을 데이터로 매핑하고 그 데이터를 설명합니다. 속성이나 자식이 있는 요소마다 클래스, 키마다 val이 생기고 클래스에는 kotlinx.serialization의 @Serializable이 붙습니다.
키가 코틀린 이름으로 맞지 않으면 @SerialName이 붙습니다. 속성 sku는 @SerialName("@sku") val sku: String, 텍스트 키는 @SerialName("#text") val text: String으로 선언됩니다. 이 클래스는 변환된 JSON을 Json.decodeFromString으로 디코딩하는 용도이며, 원본 XML을 읽으려면 별도의 XML 포맷 라이브러리와 어노테이션이 필요합니다.
입력은 엄격한 XML 1.0 파서가 처리하고 오류에는 정확한 행과 열을 알려 주며, 20 MiB까지 업로드 없이 받습니다.
사용 방법
XML 붙여넣기
문서를 붙여 넣거나 예제를 불러옵니다. Kotlin 코드가 실시간으로 다시 생성됩니다.
매핑 규칙 선택
XML 데이터 매핑 패널에서 속성 접두사, 텍스트 키, 항상 배열, 숫자 추론을 정합니다.
Kotlin 옵션 정하기
루트 클래스 이름(기본
Payload), 선택 사항인 패키지, kotlinx.serialization 어노테이션을 쓸지를 고릅니다.클래스 확인
선택 키는
Long? = null처럼 기본값이 있는 프로퍼티가 되어 키가 없어도 디코딩됩니다.복사 또는 다운로드
코드를 복사하거나 루트 클래스 이름의
Payload.kt로 내려받습니다.
작동 원리
데이터 키와 Kotlin 타입
여기서 코틀린의 정수형은 하나뿐이라, 크기와 상관없이 정수는 Long, 소수는 Double입니다. 어떤 값이 숫자인지는 매핑 규칙이 정하므로 007이나 2^53보다 큰 ID는 String으로 남습니다.
| XML | Kotlin |
|---|---|
<name>Ada</name> | val name: String |
id="7" | @SerialName("@id") val id: Long |
<price>19.5</price> | val price: Double |
<ok>true</ok> | val ok: Boolean |
반복되는 <item> | val item: List<PayloadItem> |
| 일부 item에만 있는 키 | val qty: Long? = null |
<v>1</v><v>a</v> | List<JsonElement>, import 추가 |
SerialName, null 기본값, 직렬화 스위치
프로퍼티 이름은 접두 문자를 뺀 키의 카멜 케이스입니다. xml:lang은 xmlLang, @data-id는 dataId가 되고 각각 원래 키를 담은 @SerialName이 붙습니다. kotlinx.serialization 옵션을 끄면 @Serializable과 @SerialName이 모두 사라져, 이름이 키와 맞지 않는 평범한 데이터 클래스가 됩니다.
반복 요소는 키의 합집합을 가진 클래스 하나로 합쳐지고, 일부에만 있는 키는 null 기본값을 가진 nullable이 됩니다. 알 수 없거나 섞인 값은 JsonElement입니다.
@Serializable
data class PayloadOrderItem(
@SerialName("@sku") val sku: String,
@SerialName("@qty") val qty: Long? = null,
)리스트와 단일 자식
<item>이 하나면 프로퍼티는 클래스 자체이고 둘이면 List입니다. 항상 배열 스위치를 켜면 두 경우 모두 List<T>가 유지되어 두 번째 형태에서 Json.decodeFromString이 SerializationException을 던지지 않습니다.
실제 예시
<order id="1042"><item sku="A1" qty="1">Pen</item><item sku="B7">Ink</item></order>import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Payload(
val order: PayloadOrder,
)
@Serializable
data class PayloadOrder(
@SerialName("@id") val id: Long,
val item: List<PayloadOrderItem>,
)
@Serializable
data class PayloadOrderItem(
@SerialName("@sku") val sku: String,
@SerialName("@qty") val qty: Long? = null,
@SerialName("#text") val text: String,
)qty는 한 item에만 있어 null 기본값의 Long?입니다. 요소 텍스트는 SerialName이 #text인 text 프로퍼티가 됩니다.
<p><zip>02134</zip><qty>3</qty><price>19.5</price><ok>true</ok><note><![CDATA[42]]></note></p>import kotlinx.serialization.Serializable
@Serializable
data class Payload(
val p: PayloadP,
)
@Serializable
data class PayloadP(
val zip: String,
val qty: Long,
val price: Double,
val ok: Boolean,
val note: String,
)zip은 앞자리 0 때문에 String, qty는 Long, price는 Double, ok는 Boolean입니다. CDATA 값은 추론하지 않으므로 note는 String입니다.
<doc xml:lang="en" data-id="5"><title>Hi</title></doc>data class Payload(
val doc: PayloadDoc,
)
data class PayloadDoc(
val xmlLang: String,
val dataId: Long,
val title: String,
)어노테이션이 없는 평범한 데이터 클래스입니다. xmlLang, dataId가 @xml:lang, @data-id와 연결되지 않으므로 키를 직접 매핑할 때만 쓰세요.
자주 하는 실수
컴파일러 플러그인이 필요합니다
@Serializable은 Gradle에kotlinx-serialization플러그인과kotlinx-serialization-json의존성을 추가해야 동작합니다. 없으면 컴파일되지 않습니다.모르는 키는 기본적으로 실패합니다
Json.decodeFromString은 기본적으로 선언되지 않은 키를 만나면 예외를 던집니다. 문서에 추가 요소가 올 수 있다면Json을ignoreUnknownKeys = true로 만드세요.정수는 모두 Long
Int로 충분한 값도Long으로 나옵니다. API가Int를 요구하면 직접 바꾸세요.혼합 콘텐츠는 순서를 잃습니다
자식 태그 사이에 텍스트가 있는 요소는 경고가 나오고 텍스트는 텍스트 키 아래에 모입니다. 클래스로는 원래의 텍스트·태그 순서를 복원할 수 없습니다.
자주 묻는 질문
어노테이션은 어떤 라이브러리 것인가요?
kotlinx.serialization입니다. @Serializable과 @SerialName이 여기서 오고, JsonElement import는 종류가 섞인 값이 있을 때만 나타납니다.
XML을 바로 디코딩할 수 있나요?
이 클래스로는 안 됩니다. XML to JSON 변환기 등으로 먼저 JSON으로 매핑한 뒤 그 JSON을 디코딩하세요. XML을 직접 읽으려면 별도의 포맷 라이브러리가 필요합니다.
프로퍼티에 = null이 붙는 이유는 무엇인가요?
그 요소의 일부 발생에 해당 키가 없었기 때문입니다. 기본값이 있으면 키가 없어도 디코딩이 성공합니다.
속성 키는 어떻게 바꾸나요?
매핑 패널에서 속성 접두사를 고치면 됩니다. 프로퍼티 이름은 그대로고 @SerialName 문자열이 새 접두사를 따라갑니다.
Moshi나 Gson을 쓰면 어떻게 하나요?
어노테이션 옵션을 끄고 라이브러리 고유의 어노테이션, 예를 들어 Moshi의 @Json(name = "@id")를 직접 붙이세요. 프로퍼티 이름과 타입은 그대로 쓸 수 있습니다.
브라우저 밖으로 나가는 데이터가 있나요?
없습니다. 파싱과 생성이 모두 로컬에서 실행됩니다.
마지막 업데이트:
