使用 VTD-XML 删除属性时如何 trim 元素名称
How to trim element name when removing attributes with VTD-XML
给出以下 xml 片段
<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>
使用 VTD-XML 删除名称空间属性对以下代码段效果很好:
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 );
}
}
结果显示元素没有属性但中间的空格没有被删除:
<l:Variable >
<!-- some more content --!>
</l:Variable>
navigator.expandWhiteSpaces( l )
等人的用法。不起作用,因为这些方法适用于元素而不适用于属性。
总结一下:是否可以删除属性以获得类似
的结果
<l:Variable>
<!-- some more content --!>
</l:Variable>
首先,我认为您可以使用以下两种方式之一更简洁地编码 "starts-with"...
第一个使用了starts-with()的xpath函数。它在技术上是一个 xpath 2.0 函数,但它们在 vtd-xml 的 xpath 实现中受支持。连同 contains() 和 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) );
//}
}
或者您可以直接使用 VTDNav 的 startWith、contains 或 endWith 函数,而不是显式地创建一个字符串对象 (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 );
//}
}
无论哪种方式,我认为在属性 name-value 对段上应用 expandWhitespace 可能有点危险,因为您可能会不小心删除定界空白并弄乱 well-formed xml 文档...
目前,清理 throw-away 个空格是 work-in-progress。我希望这不是一个表演障碍。如果是这样,您将不得不手动完成……这将是一个有点乏味的编码。但你必须
找到属性名称值段的开始和结束偏移量
将起始偏移量和长度编码为 64 位整数。
使用正确的参数调用 trimWhitespace 以删除末尾多余的空格...
受 vtd-xml-author 提示的启发,我现在的解决方法片段是
while ((i = autoPilot.evalXPath()) != -1)
{
xm.removeAttribute( i );
xm.removeContent( navigator.getTokenOffset( i ) - 1, 1 );
}
这假设属性的前导空白属于它,因此也被删除。所有其他空白将被忽略并保持不变。
给出以下 xml 片段
<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>
使用 VTD-XML 删除名称空间属性对以下代码段效果很好:
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 );
}
}
结果显示元素没有属性但中间的空格没有被删除:
<l:Variable >
<!-- some more content --!>
</l:Variable>
navigator.expandWhiteSpaces( l )
等人的用法。不起作用,因为这些方法适用于元素而不适用于属性。
总结一下:是否可以删除属性以获得类似
的结果<l:Variable>
<!-- some more content --!>
</l:Variable>
首先,我认为您可以使用以下两种方式之一更简洁地编码 "starts-with"... 第一个使用了starts-with()的xpath函数。它在技术上是一个 xpath 2.0 函数,但它们在 vtd-xml 的 xpath 实现中受支持。连同 contains() 和 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) );
//}
}
或者您可以直接使用 VTDNav 的 startWith、contains 或 endWith 函数,而不是显式地创建一个字符串对象 (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 );
//}
}
无论哪种方式,我认为在属性 name-value 对段上应用 expandWhitespace 可能有点危险,因为您可能会不小心删除定界空白并弄乱 well-formed xml 文档...
目前,清理 throw-away 个空格是 work-in-progress。我希望这不是一个表演障碍。如果是这样,您将不得不手动完成……这将是一个有点乏味的编码。但你必须
找到属性名称值段的开始和结束偏移量
将起始偏移量和长度编码为 64 位整数。
使用正确的参数调用 trimWhitespace 以删除末尾多余的空格...
受 vtd-xml-author 提示的启发,我现在的解决方法片段是
while ((i = autoPilot.evalXPath()) != -1)
{
xm.removeAttribute( i );
xm.removeContent( navigator.getTokenOffset( i ) - 1, 1 );
}
这假设属性的前导空白属于它,因此也被删除。所有其他空白将被忽略并保持不变。