Given following xml snippet
<l:Variable xmlns="ddi:instance:3_2" xmlns:g="ddi:group:3_2" xmlns:l="ddi:logicalproduct:3_2" xmlns:r="ddi:reusable:3_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- some more content --!>
</l:Variable>
removing namespace attributes with VTD-XML works well with following snippet:
private String removeNamespaces( String xml )
{
try
{
VTDGen generator = new VTDGen();
generator.setDoc( xml.getBytes() );
generator.parse( false );
VTDNav navigator = generator.getNav();
XMLModifier xm = new XMLModifier( navigator );
AutoPilot autoPilot = new AutoPilot( navigator );
autoPilot.selectXPath( "@*" );
int i = -1;
while ((i = autoPilot.evalXPath()) != -1)
{
if ( navigator.toString( i ).startsWith( "xmlns" ) )
{
xm.removeAttribute( i );
}
}
XMLByteOutputStream xbos = new XMLByteOutputStream( xm.getUpdatedDocumentSize() );
xm.output( xbos );
return new String( xbos.getXML() );
}
catch (Exception e)
{
throw new RuntimeException( e );
}
}
The result shows the element without the attributes but the blanks between have not be deleted:
<l:Variable >
<!-- some more content --!>
</l:Variable>
Usage of navigator.expandWhiteSpaces( l )
et al. does not work because these methods are for elements but not for attributes.
To sum it up: Is it possible to remove attributes to get to a result like
<l:Variable>
<!-- some more content --!>
</l:Variable>
First of all, I think you can code "starts-with" more concisely in one of the two ways... The first one uses the xpath function of starts-with(). It is technically a xpath 2.0 function, but they are supported in vtd-xml's xpath implementation.. along with contains() and ends-with()...
generator.parse( false );
VTDNav navigator = generator.getNav();
XMLModifier xm = new XMLModifier( navigator );
AutoPilot autoPilot = new AutoPilot( navigator );
autoPilot.selectXPath( "@*[starts-with(.,'xmlns')]" );
int i = -1;
while ((i = autoPilot.evalXPath()) != -1)
{
// if ( navigator.toString( i ).startsWith( "xmlns" ) )
//{
xm.removeAttribute( navigator.trimWhiteSpaces(i) );
//}
}
Or you can use VTDNav's startWith,contains or endWith functions directly, instead of explicity bringing a string object into existence (navigator.toString)
VTDNav navigator = generator.getNav();
XMLModifier xm = new XMLModifier( navigator );
AutoPilot autoPilot = new AutoPilot( navigator );
autoPilot.selectXPath( "@*" );
int i = -1;
while ((i = autoPilot.evalXPath()) != -1)
{
// if ( navigator.toString( i ).startsWith( "xmlns" ) )
//{
if (navigator.startsWith(i, "xmlns"))
xm.removeAttribute( i );
//}
}
Either way, i think that applying expandWhitespace on an attribute name-value pair segment may be a bit dangerous, since you could remove accidentally the delimiting white spaces and mess up a well-formed xml document...
Currently, cleaning up the throw-away white spaces is a work-in-progress. I hope it is not a show stopper. If it is, you will have to do it manually... it will be a bit tedious coding. But you will have to
find the start, and end offset of the attribute name value segment
Encoding the start offset and length into a 64-bit integer.
Call trimWhitespace with the right parameters to remove the extraneous white spaces at the end...