Skip to content

Commit

Permalink
For strings in the NullDecoder only return the empty string if the el…
Browse files Browse the repository at this point in the history
…ement is a value child (otherwise the empty value is not present - missing tag or attribute).
  • Loading branch information
pdvrieze committed Mar 13, 2024
1 parent 9947c83 commit 364f481
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
Expand Up @@ -498,13 +498,13 @@ internal open class XmlDecoderBase internal constructor(
* Special class that handles null values that are not mere primitives. Nice side-effect is that XmlDefault values
* are actually parsed as XML and can be complex
*/
private inner class NullDecoder(xmlDescriptor: XmlDescriptor) :
private inner class NullDecoder(xmlDescriptor: XmlDescriptor, val isValueChild: Boolean) :
XmlDecoder(xmlDescriptor), CompositeDecoder {

override fun decodeNotNullMark() = (xmlDescriptor as? XmlValueDescriptor)?.default != null

override fun decodeStringImpl(defaultOverEmpty: Boolean): String {
if (!defaultOverEmpty) return ""
if (isValueChild && (!defaultOverEmpty)) return ""
val default = (xmlDescriptor as? XmlValueDescriptor)?.defaultValue(this@XmlDecoderBase, String.serializer())
return default ?: ""
}
Expand Down Expand Up @@ -692,13 +692,13 @@ internal open class XmlDecoderBase internal constructor(
index: Int,
deserializer: DeserializationStrategy<T>
): XmlDecoder? {
if (nulledItemsIdx >= 0) return null

val childXmlDescriptor = xmlDescriptor.getElementDescriptor(index)

val effectiveDeserializer = childXmlDescriptor.effectiveDeserializationStrategy(deserializer)

return when {
nulledItemsIdx >= 0 -> null

effectiveDeserializer.descriptor.kind is PrimitiveKind ->
XmlDecoder(childXmlDescriptor, currentPolyInfo, lastAttrIndex)

Expand Down Expand Up @@ -742,7 +742,7 @@ internal open class XmlDecoderBase internal constructor(
AttributeMapDecoder(childXmlDescriptor, lastAttrIndex)
} else {
serialElementDecoder(descriptor, index, effectiveDeserializer)
?: NullDecoder(childXmlDescriptor)
?: NullDecoder(childXmlDescriptor, isValueChild)
}

val result: T = when (effectiveDeserializer) {
Expand All @@ -761,8 +761,13 @@ internal open class XmlDecoderBase internal constructor(
is AbstractCollectionSerializer<*, T, *> ->
effectiveDeserializer.merge(decoder, previousValue)

else ->
else -> try {
effectiveDeserializer.deserialize(decoder)
} catch (e: XmlException) {
throw e
} catch (e: Exception) {
throw XmlException("In: ${xmlDescriptor.tagName}/${descriptor.getElementName(index)} Error: ${input.extLocationInfo} - ${e.message}", input.extLocationInfo, e)
}
}

val tagId = (decoder as? SerialValueDecoder)?.tagIdHolder?.tagId
Expand Down
Expand Up @@ -20,8 +20,9 @@

package nl.adaptivity.xml.serialization

import io.github.pdvrieze.xmlutil.testutil.assertXmlEquals
import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.XmlEvent
import nl.adaptivity.xmlutil.*
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlElement
import nl.adaptivity.xmlutil.serialization.XmlValue
Expand All @@ -33,9 +34,9 @@ class TestCompactFragmentSerializer {
@Test
fun testSerializeCompactFragment() {
val f = FragmentContainer(CompactFragment(listOf(XmlEvent.NamespaceImpl("ns", "urn:ns")), """<ns:a><ns:b>"hello"</ns:b></ns:a>"""), "bar")
val expected = "<FragmentContainer xmlns:ns=\"urn:ns\" c=\"bar\">${f.fragment.contentString}</FragmentContainer>"
val expected = "<FragmentContainer c=\"bar\" xmlns:ns=\"urn:ns\">${f.fragment.contentString}</FragmentContainer>"
val actual = XML.Companion.encodeToString(f)
assertEquals(expected, actual)
assertXmlEquals(expected, actual)
}

@Test
Expand Down

0 comments on commit 364f481

Please sign in to comment.