Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue migrating to 0.90.1, unable to access nl.adaptivity.xmlutil.core.impl.idom.INodeList #234

Open
jbruchanov opened this issue Aug 19, 2024 · 7 comments

Comments

@jbruchanov
Copy link

jbruchanov commented Aug 19, 2024

Having KMP project for android/ios/jvm, going from 0.86.3 to 0.90.1

toml:

xmlutil = "0.90.1"

xmlutil-core = { module = "io.github.pdvrieze.xmlutil:core", version.ref = "xmlutil" }
xmlutil-serialization = { module = "io.github.pdvrieze.xmlutil:serialization", version.ref = "xmlutil" }
xmlutil-serialutil = { module = "io.github.pdvrieze.xmlutil:serialutil", version.ref = "xmlutil" }

I need to iterate over nl.adaptivity.xmlutil.dom.Node#childNodes which is a type of nl.adaptivity.xmlutil.core.impl.idom.INodeList
however IDE can't recognize this type (in commonMain, nor jvmTest).

My hunch is that there is some issue with the release, I can navigate to source code in IDE, seeing
...0.90.1-commonMain..., but the INodeList is coming from ...0.90.1-commonDomMain...,
however compiler looks like it doesn't see the part of commonDomMain

am I missing something extra dependency what needs to be brought in or what am I missing ?

@pdvrieze
Copy link
Owner

It is quite possible that this is an IDE problem. Does it work in gradle itself? If it is an ide issue, it might be that it works in k2 mode. Otherwise if you could have a reproducer that would help.

Please also note that there are still some cache issues with multiplatform code, and sometimes resetting IDE state can help.

jbruchanov added a commit to jbruchanov/KMPMultiProject that referenced this issue Aug 19, 2024
@jbruchanov
Copy link
Author

jbruchanov commented Aug 19, 2024

@pdvrieze
doesn't look like it's IDE issue, gradle itself is failing with

> Task :shared:compileDebugKotlinAndroid
e: file:///F:/2Projects/_Jibru/KMPMultiProject/LibsProject/shared/src/commonMain/kotlin/com/example/libsproject/XmlExample.kt:11:33 Unresolved reference 'forEachBfsIndexed'.
e: file:///F:/2Projects/_Jibru/KMPMultiProject/LibsProject/shared/src/commonMain/kotlin/com/example/libsproject/XmlExample.kt:11:53 Cannot infer type for this parameter. Please specify it explicitly.

reproducer
https://github.com/jbruchanov/KMPMultiProject/tree/xmlutil-234

image

@pdvrieze
Copy link
Owner

I've had a look at the example. There are some issues with consistency of the types used. The recommended way to work is to use nl.adaptivity.xmlutil.dom2.Element and nl.adaptivity.xmlutil.dom2.NodeList as well as Element.serializer. I will deprectate the serializer in the serialization package (this forwards to the other anyway).

With those small changes your example works

@jbruchanov
Copy link
Author

@pdvrieze
Hi thanks, that helped.
Would you be able to help me with different issue though ?

I'm trying to parse this xml...

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <s:Fault>
            <detail>
                <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
                    <errorCode>401</errorCode>
                    <errorDescription>Invalid Action</errorDescription>
                </UPnPError>
            </detail>
            <faultcode>s:Client</faultcode>
            <faultstring>UPnPError</faultstring>
        </s:Fault>
    </s:Body>
</s:Envelope>

<UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
and need the xmlns on this ^ node.

0.86.3 version I was using

node.lookupNamespaceURI(node.prefix ?: "") ?: "" and that returned the urn:schemas-upnp-org:control-1-0 value...

however with new version, lookupNamespaceURI returns null and there is no "attributes" property on nl.adaptivity.xmlutil.dom2.Node

exploring via eval window in IDE and I have to cast the node to nl.adaptivity.xmlutil.dom2.Element to have access to attributes.
but that explicit cast seems to be wrong, what's the correct (type safe) way of getting attributes in current usecase ?

I'm currently doing main traversal via this

private val xmlParser = XML { autoPolymorphic = true }
val xml = "^^^ xml"
xmlParser.decodeFromString(Element.serializer(), xml)
   .getChildNodes()

@pdvrieze
Copy link
Owner

Basically the dom2 namespace is for a platform independent dom interface as multiplatform complains with the old approach of type-aliasing the actual implementations directly. Attributes are reserved for elements, so the interface has no attribute on node, but it should be possible to look up namespace uri's as nodes still have parent elements. This seems like a regression.

However, if you want to determine the namespace for an element/attribute you should just use the namespaceUri attribute on elements/attributes (with the caveat that attributes are normally in the null namespace).

@pdvrieze
Copy link
Owner

pdvrieze commented Sep 11, 2024

Have a look at:

@Test
fun testResponse3_234() {
val xml: XML = XML { recommended_0_90_2() }
val soap = xml.decodeFromString<Envelope<Fault>>(SOAP_RESPONSE3)
val fault = soap.body.child
assertNull(fault.role)
assertNull(fault.node)
assertEquals("s:Client", fault.code.textContent)
val ns = fault.code.lookupNamespaceURI("s")
assertEquals(Envelope.NAMESPACE, ns)
val reasonText = assertIs<Element>(fault.reason.childNodes.singleOrNull { ! (it is Text && isXmlWhitespace(it.data))} )
val reason = assertIs<Text>(reasonText.childNodes.singleOrNull())
assertEquals("UPnPError", reason.textContent)
val detail = assertIs<Element>(fault.detail?.childNodes?.singleOrNull { (it !is Text) || !isXmlWhitespace(it.data) })
assertEquals("UPnPError", detail.localName)
assertEquals("urn:schemas-upnp-org:control-1-0", detail.namespaceURI)
val errorChildren = detail.childNodes.filterNot { it is Text && isXmlWhitespace(it.data) }
assertEquals(2, errorChildren.size)
}

Also see the soap class implementations in https://github.com/pdvrieze/xmlutil/tree/dev/serialization/src/commonTest/kotlin/nl/adaptivity/xml/serialization/regressions/soap/

Note that your xml actually uses an invalid non-standard namespace for soap (and the Fault element is not valid per the specification), I changed this in the test code. The structure you have is from a draft, and then re-namespaced.

@jbruchanov
Copy link
Author

@pdvrieze
thanks I'll have a look...
for the invalid soap, well, not much I can do about, at least it's not invalid xml :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants