所提供的是:
XML结构,如
<span class="abbreviation">AGB<span class"explanation">Allgemeine Geschäftsbedingungen</span></span>改造后的结果应该是:
<abbr title="Allgemeine Geschäftsbedingungen">AGB</abbr>我知道SAX是一个基于事件的XML解析器,它的方法如下
#startElement(...)#endElement(...)我可以捕获事件(如open-a-tag、close-a-tag)和
#characters我可以提取标签之间的文字。
我的问题是:
我是否可以创建上面提到的转换(是否可能)?
我的问题是:
发布于 2017-03-02 09:49:19
答案是,,有可能!
从这个StackOverflow-link中可以得到的主要参数/提示
以下是必须做的工作:
#character方法完成)abbr-tag。为了完整起见,这里是coremedia过滤器的源代码:
import com.coremedia.blueprint.cae.richtext.filter.FilterFactory;
import com.coremedia.xml.Filter;
import org.apache.commons.lang3.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GlossaryFilter extends Filter implements FilterFactory {
private static final String SPAN = "span";
private static final String CLASS = "class";
private boolean isAbbreviation = false;
private boolean isExplanation = false;
private String abbreviation;
private String currentUri;
private boolean spanExplanationClose = false;
private boolean spanAbbreviationClose = false;
@Override
public Filter getInstance(final HttpServletRequest request, final HttpServletResponse response) {
return new GlossaryFilter();
}
@Override
public void startElement(final String uri, final String localName, final String qName,
final Attributes attributes) throws SAXException {
if (isSpanAbbreviationTag(qName, attributes)) {
isAbbreviation = true;
} else if (isSpanExplanationTag(qName, attributes)) {
isExplanation = true;
currentUri = uri;
} else {
super.startElement(uri, localName, qName, attributes);
}
}
private boolean isSpanExplanationTag(final String qName, final Attributes attributes) {
//noinspection OverlyComplexBooleanExpression
return StringUtils.isNotEmpty(qName) && qName.equalsIgnoreCase(SPAN) && (
attributes.getLength() > 0) && attributes.getValue(CLASS).equals("explanation");
}
private boolean isSpanAbbreviationTag(final String qName, final Attributes attributes) {
//noinspection OverlyComplexBooleanExpression
return StringUtils.isNotEmpty(qName) && qName.equalsIgnoreCase(SPAN) && (
attributes.getLength() > 0) && attributes.getValue(CLASS).equals("abbreviation");
}
@Override
public void endElement(final String uri, final String localName, final String qName)
throws SAXException {
if (spanExplanationClose) {
spanExplanationClose = false;
} else if (spanAbbreviationClose) {
spanAbbreviationClose = false;
} else {
super.endElement(uri, localName, qName);
}
}
@Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
if (isAbbreviation && isExplanation) {
final String explanation = new String(ch, start, length);
final AttributesImpl newAttributes = createAttributes(explanation);
writeAbbrTag(newAttributes);
changeState();
} else if (isAbbreviation && !isExplanation) {
abbreviation = new String(ch, start, length);
} else {
super.characters(ch, start, length);
}
}
private void changeState() {
isExplanation = false;
isAbbreviation = false;
spanExplanationClose = true;
spanAbbreviationClose = true;
}
@SuppressWarnings("TypeMayBeWeakened")
private void writeAbbrTag(final AttributesImpl newAttributes) throws SAXException {
super.startElement(currentUri, "abbr", "abbr", newAttributes);
super.characters(abbreviation.toCharArray(), 0, abbreviation.length());
super.endElement(currentUri, "abbr", "abbr");
}
private AttributesImpl createAttributes(final String explanation) {
final AttributesImpl newAttributes = new AttributesImpl();
newAttributes.addAttribute(currentUri, "title", "abbr:title", "CDATA", explanation);
return newAttributes;
}
}有趣的地方在于方法:
startElement(...)endElement(...)characters(...)startElement(.)
在这里,您存储sax解析器所在的标记所在的状态(更详细的:存储状态,打开的是跨标记( "class=abbreviation“或"class=explanation")。
isAbbreviation用于打开带有"class=abbreviation“的跨标记。isExplanation用于打开带有"class=explanation“的跨标记。你只存储状态。所述的跨标记将不会被处理/过滤(结果是,它们将被删除)。每个其他标记都是在没有过滤的情况下处理的,它们将不受修改地应用(即else-block)。
endElement(.)
在这里,您只需要处理每个标记,除了(所提到的span标记)。所有这些标记都是不经修改而应用的( else-block)。如果sax解析器位于封闭的span-标记(带有"class=abbreviation“或"class=explanation"),则什么也不想做(除了存储状态)。
字符(.)
在这个方法中,奇迹发生了(用解析器创建一个标记)。取决于国家:
(isAbbreviation && isExplanation)。isAbbreviation && !isExplanation)。else第三州。
只需复制你找到的文本
第二州。
提取带"class=abbreviation“的span标记的内容,供以后使用。
第三州。
abbr-tag (title=....)创建属性abbr-tag (而不是两个span标记)https://stackoverflow.com/questions/42509487
复制相似问题