首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以将XML-元素与SAX (coremedia CAE filter)合并吗?

可以将XML-元素与SAX (coremedia CAE filter)合并吗?
EN

Stack Overflow用户
提问于 2017-02-28 13:03:22
回答 1查看 96关注 0票数 0

所提供的是:

XML结构,如

代码语言:javascript
复制
<span class="abbreviation">AGB<span class"explanation">Allgemeine Geschäftsbedingungen</span></span>

改造后的结果应该是:

代码语言:javascript
复制
<abbr title="Allgemeine Geschäftsbedingungen">AGB</abbr>

我知道SAX是一个基于事件的XML解析器,它的方法如下

  • #startElement(...)
  • #endElement(...)

我可以捕获事件(如open-a-tagclose-a-tag)和

  • #characters

我可以提取标签之间的文字。

我的问题是:

我是否可以创建上面提到的转换(是否可能)?

我的问题是:

  • 我可以提取缩写文本和解释文本。
  • 我可以在最后一个span标签上调用#startElement
  • 但是我无法创建标签的内容(在本例中是文本'ABG')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-02 09:49:19

答案是,有可能!

从这个StackOverflow-link中可以得到的主要参数/提示

以下是必须做的工作:

  1. 您必须记住sax解析器所处的span标记所在的状态("class=abbreviation“或"class=explanation")。
  2. 您必须提取标记的内容(这可以通过#character方法完成)
  3. 当您知道sax解析器的状态和内容时,您可以创建一个新的abbr-tag。
  4. 所有其他标签,必须加入而不作任何修改。

为了完整起见,这里是coremedia过滤器的源代码:

代码语言:javascript
复制
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"),则什么也不想做(除了存储状态)。

字符(.)

在这个方法中,奇迹发生了(用解析器创建一个标记)。取决于国家:

  1. Sax解析器位于带有"class=explanation“的span标记上(这意味着前面传递了"class=abbreviation”的打开的span标记) -->分支(isAbbreviation && isExplanation)
  2. Sax解析器位于第一个span-标记(带有“class=abbreviation”的span-标记)->分支(isAbbreviation && !isExplanation)。
  3. 在任何其他标记中找到的所有其他字符-->分支else

第三州。

只需复制你找到的文本

第二州。

提取带"class=abbreviation“的span标记的内容,供以后使用。

第三州。

  • 使用"class=explanation“提取span标记的内容。
  • abbr-tag (title=....)创建属性
  • 编写新的abbr-tag (而不是两个span标记)
  • 设置状态
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42509487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档