2

I'd like to use Apache XMLBeans to escape a String for embedding it in an XML document, e.g. encode all XML entities.

XmlString does provide this functionality, but insists on wrapping the output in xml-fragment tags, which I'd like to get rid of.

However, I'm not interested in sugestions

  • to use anything other than XMLBeans (like org.apache.commons.lang.StringEscapeUtils)
  • to remove the enclosing tag after escaping (e.g. using a regex)

Here's a test case. Can you help me fix it?

import org.apache.xmlbeans.*;

public class Test {
  @Test public void test(){
    String input = "You & me";
    String expected = "You & me";
    String actual = escape(input);
    Assert.assertEquals(expected, actual);
    // Fails with: ComparisonFailure: expected:<[You &amp; me]> 
    //             but was:<[<xml-fragment>You &amp; me</xml-fragment>]>
  }

  private String escape(String str){
    XmlString value = XmlString.Factory.newInstance();
    value.setStringValue(input);
    XmlOptions opts = new XmlOptions();
    // do I need to set one of the 54 available options?
    // see http://xmlbeans.apache.org/docs/2.4.0/reference/org/apache/xmlbeans/XmlOptions.html
    return value.xmlText(opts);
  }
}
otto.poellath
  • 4,129
  • 6
  • 45
  • 60
  • I'd be pretty surprised if XmlBeans didn't automatically escape what must be escaped. Why do you want to escape manually? – JB Nizet Jul 08 '11 at 11:40
  • JB Nizet: I'm using XMLBeans to implement parts of a custom XML marshalling framework. I didn't mean to imply that XmlBeans wouldn't automatically escape what must be escaped. – otto.poellath Jul 08 '11 at 17:07
  • Why can't you use e.g. StringEscapeUtils? This may reveal some requirement that's not clear. – Ed Staub Jul 11 '11 at 00:25
  • Ed: I could indeed use StringEscapeUtils, and that's what I'm currently using. But given that the required functionality is already in XMLBeans, I'd like to get rid of the Commons Lang dependency. – otto.poellath Jul 11 '11 at 12:41

3 Answers3

1

Use the setSaveOuter() option before passing the XmlOptions to the xmlText() method. Like this.

XmlOptions opts = new XmlOptions();
opts.setSaveOuter();
return value.xmlText(opts);

I would like to clarify that if you just create a new element out of thin air it seems like the element name will not be serialized. For example If I have a Model element that has a Property element on it the following will not display the property tag, it will display the xml fragment.

Property property = Property.Factory.newInstance(); 

XmlOptions opts = new XmlOptions();
opts.setSaveOuter();
return property.xmlText(opts);

To have the Property Element show up I must do the following.

ModelDocument modelDoc = ModelDocument.Factory.newInstance();
ModelType model = modelDoc.addNewModel();
PropertyType propertyType = model.addNewProperty();
Property property = Property.Factory.newInstance(); 

XmlOptions opts = new XmlOptions();
opts.setSaveOuter();
return property.xmlText(opts);
decal
  • 987
  • 2
  • 14
  • 39
  • I have tried and this is not working.I even tried [this link](http://osdir.com/ml/user-xmlbeans.apache.org/2009-12/msg00020.html). Any help is appreciated. – dileepVikram Oct 08 '14 at 06:24
  • +1 on this answer, worked for me - not sure why it didnt work for you dileepvikram - I just added this before i created a JMS TextMessage object `XmlOptions opts = new XmlOptions();` `opts.setSaveOuter();` and then just added the "opts" here: `sendMessage(_OrderStateChangeEventTypeImpl.xmlText(opts));` And it worked like a charm – JGlass Nov 28 '17 at 21:06
0

your expected string is incorrect. by virtue of calling xmlText, it will return an XML, hence the string must be wrapped in xml-fragment element.

0

create xml reader as a normal xml string then remove the xml-fragment, i have tried like this,

if(request != null && request.contains("<xml")){
XMLInputFactory xif = XMLInputFactory.newFactory();
StringReader reader = new StringReader(request);
StreamSource xml = new StreamSource(reader);
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
xsr.nextTag();          
request = xsr.getElementText();
System.out.println("updated request is \n"+request);
}

then

JAXBContext jaxbContext = JAXBContext.newInstance(YourClass.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(request);