I've just written a quick script that creates a component via the core service. FWIW, the powershell exposes ComponentData.Content as a string, and I just shoved in something like:
<Content xmlns="uuid:985d42e5-976f-46e1-9727-772cb961353f">
<NewField></NewField>
</Content>
This showed up exactly like that in the component.
I wouldn't expect the RTF XSLT to modify the content when written via the core service (or TOM.NET or any other API. The XSLT cleanup is a GUI operation, albeit these days implemented via a back-end service. If you create content via code, it's on you to send clean data. Obviously, when you open the component up in the GUI, the slightest modification will cause the XSLT to fire.
So to summarise: it doesn't look like the data goes via an XML document to get across the wire to the core service. (Mind you, I'm using nettcp = hope /that/ abstraction isn't leaking!) Usually when <x></x>
gets transformed to <x/>
it's because the document has been deserialised to the infoset representation. So does your implementation load this into a DOM?
Edit: Per your comment suggestion, I altered my input. I had to put the p in the xhtml namespace, and provide a closing
, but on opening via the gui, I found this in the source.
<Content xmlns="uuid:985d42e5-976f-46e1-9727-772cb961353f">
<NewField>
<p xmlns="http://www.w3.org/1999/xhtml">this is a test <a name="abc" id="abc"></a></p>
</NewField>
</Content>
... so still, the conclusion remains that it may not be the core service that is collapsing your elements.
Further edit:
In the source tab of the RTF I get:
<p>this is a test <a name="abc" id="abc"/></p>