繁体   English   中英

使用Woodstox解析XML时,保持实体不变

[英]Leave entities as-is when parsing XML with Woodstox

我正在使用Woodstox处理一个XML,其中包含一个节点的值中的某些实体(最值得注意的是> )。 使用一个极端的例子,它是这样的:

<parent>&nbsp; &lt; &nbsp; &gt; &amp; &quot; &apos; &nbsp;</parent>

我为WstxInputFactoryIS_REPLACING_ENTITY_REFERENCESP_TREAT_CHAR_REFS_AS_ENTSP_CUSTOM_INTERNAL_ENTITIES ...)和WstxOutputFactory尝试了很多不同的配置选项,但无论我尝试什么,输出总是这样:

<parent>nbsp; &lt; nbsp; > &amp; " ' nbsp;</parent>

&gt;转换为>&lt;保持不变, &nbsp;失去& ...)

我正在使用创建的XMLEventReader读取XML

XMLEventReader reader = wstxInputFactory.createXMLEventReader(new StringReader(fulltext));

配置WstxInputFactory后

是否有任何方法可以将Woodstox配置为忽略所有实体并输出与输入String中的文本完全相同的文本?

将始终处理基本的五个XML实体(quot,amp,apos,lt,gt)。 据我所知,没有办法用萨克斯获得它们的来源。

对于其他实体,您可以手动处理它们。 您可以捕获事件直到元素结束并连接值:

    XMLInputFactory factory = WstxInputFactory.newInstance();
    factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
    XMLEventReader xmlr = factory.createXMLEventReader(
            this.getClass().getResourceAsStream(xmlFileName));

    String value = "";
    while (xmlr.hasNext()) {
        XMLEvent event = xmlr.nextEvent();
        if (event.isCharacters()) {
            value += event.asCharacters().getData();
        }
        if (event.isEntityReference()) {
            value += "&" + ((EntityReference) event).getName() + ";";
        }
        if (event.isEndElement()) {
            // Assign it to the right variable
            System.out.println(value);
            value = "";
        }
    }

对于您的示例输入:

<parent>&nbsp; &lt; &nbsp; &gt; &amp; &quot; &apos; &nbsp;</parent>

输出将是:

&nbsp; < &nbsp; > & " ' &nbsp;

否则,如果要转换所有实体,可以使用自定义XmlResolver用于未声明的实体:

public class NaiveHtmlEntityResolver implements XMLResolver {

    private static final Map<String, String> ENTITIES = new HashMap<>();

    static {
        ENTITIES.put("nbsp", " ");
        ENTITIES.put("apos", "'");
        ENTITIES.put("quot", "\"");
        // and so on
    }

    @Override
    public Object resolveEntity(String publicID,
            String systemID,
            String baseURI,
            String namespace) throws XMLStreamException {
        if (publicID == null && systemID == null) {
            return ENTITIES.get(namespace);
        }
        return null;
    }
}

然后告诉Woodstox将其用于未申报的实体:

    factory.setProperty(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER, new NaiveHtmlEntityResolver());

首先,你需要包含实际代码,因为“输出总是这样的东西”没有任何意义,如果没有准确解释你如何输出被解析的内容:你可能正在打印事件,使用某些库,或者可能使用Woodstox流或事件作家。

第二:有之间少数预先定义的实体(在XML差别ltgtaposquotamp ),和arbitary用户定义实体像什么nbsp这里会。 以前你可以按原样使用,它们已经定义; 后者仅在您在DTD中定义它们时才存在。

两组的处理也不同; 无论如何都会扩展前者,这是XML规范。 后者将被解析(除非禁用解析),然后扩展 - 或者如果没有定义,将抛出异常。 您也可以通过其他答案指定自定义解析器; 但这只会用于自定义实体(此处为&nbsp; )。

最后,不要解释你正在做的事情和你想要实现的目标一样好。 这将有助于提出比“我如何做X”的具体问题更好的建议,这可能不是可行的方法。

至于Woodstox的配置,可能是这篇博文:

https://medium.com/@cowtowncoder/configuring-woodstox-xml-parser-woodstox-specific-properties-1ce5030a5173

将有所帮助(以及该系列中的其他2个) - 它涵盖了现有的配置设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM