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

ClassCastException when setting child projection on parent as document root #51

Open
zhsc opened this issue Apr 12, 2018 · 1 comment
Open

Comments

@zhsc
Copy link

zhsc commented Apr 12, 2018

I'm seeing this error while trying to set a child projection onto a parent projection where the @XBWrite segment is the document root.

Here's a test case:


import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.xmlbeam.XBProjector;
import org.xmlbeam.XBProjector.Flags;
import org.xmlbeam.annotation.XBWrite;

public class TestSetChildUnderDocumentRoot {

	public interface Child {
		@XBWrite("ChildData")
		void setData(String data);
	}
	
	public interface ParentNoRootElement {

		@XBWrite("Child")
		void setChild(Child child);
	}
		
	@Test
	public void testSetChildOnParentAsDocumentRoot() {
		XBProjector projector = new XBProjector(Flags.TO_STRING_RENDERS_XML);
		
		ParentNoRootElement parent = projector.projectEmptyDocument(ParentNoRootElement.class);
		
		Child child = projector.projectEmptyDocument(Child.class);
		child.setData("child data...");
		
		parent.setChild(child);  
		
		/* Throws:
		java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DocumentImpl cannot be cast to org.w3c.dom.Element
			at org.xmlbeam.util.intern.DOMHelper.replaceElement(DOMHelper.java:511)
			at org.xmlbeam.ProjectionInvocationHandler$WriteInvocationHandler.invokeProjection(ProjectionInvocationHandler.java:669)
			at org.xmlbeam.ProjectionInvocationHandler$ProjectionMethodInvocationHandler.invoke(ProjectionInvocationHandler.java:206)
			at org.xmlbeam.ProjectionInvocationHandler.invoke(ProjectionInvocationHandler.java:879)
			at com.sun.proxy.$Proxy5.setChild(Unknown Source)
		 */
		
		System.out.println("Result: " + parent);
		
		assertEquals(
				  "<Child>\n"
				+ "   <ChildData>child data...</ChildData>\n"
				+ "</Child>",
				parent.toString());
	}
}
@SvenEwald
Copy link
Owner

Ah... this is not possible right now, but I can give you an workaround:

public interface Child {
    @XBWrite("ChildData")
    void setData(String data);
}

public interface ParentNoRootElement {

    @XBWrite("/*")
    void setChild(Child child);
}
    
@Test
public void testSetChildOnParentAsDocumentRoot() {
    XBProjector projector = new XBProjector(Flags.TO_STRING_RENDERS_XML);
    
    ParentNoRootElement parent = projector.projectEmptyDocument(ParentNoRootElement.class);
    
    Child child = projector.projectEmptyElement("Child",Child.class);
    child.setData("child data...");
    parent.setChild(child);  
    System.out.println("Result: " + parent);
}
  1. Writing to the root nonexisting element is possible, but you need to use "/*" as XPath expression.
  2. Your Child instance was a document, which has no name for the element. You need to create an Element instead of Document as child.

I will try to make root element replacements easier in the future.

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