簡體   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