2014-05-22 49 views
2

看起來JAXP允許爲文檔節點分配任何值,包括<,>和&等。使用XML保留字符和XSLT引發了一個問題。請看下面的代碼:關於JAXP,XSLT和XML保留字符

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
Document doc = docBuilder.newDocument(); 

... 

Element field = doc.createElement("col"); 
field.setTextContent("<p>&]]"); 
row.appendChild(field); 

... 

TransformerFactory factory = TransformerFactory.newInstance(); 
Source xslt = new StreamSource(new File("templateName.xsl")); 
Transformer transformer = factory.newTransformer(xslt); 

transformer.transform(new DOMSource(doc), new StreamResult(printer)); 

現在,如果我們有

<xsl:value-of select="col" disable-output-escaping="yes"/> 
在 「templateName.xsl」

,輸出將看起來像

"<p>&]]" 

,如果我們有這樣的

<xsl:value-of select="col"/> 

輸出將是

&lt;p&gt;&amp;]] 

所以基本上我的問題是,什麼樣的內部數據表示JAXP的使用,使得該

"<p>&]]" 

是OK?它不能是文本節點,也不能是CDATA節點。它是什麼?我相信,必須爲轉換提供有效的XML文檔。另一方面,disable-output-escaping屬性表示特殊字符應該按原樣輸出,這是否意味着我們的「col」節點保留在代碼中? XML文檔如何有效呢?

回答

1

好吧,我想我已經知道它是如何工作的。除非它們位於CDATA節點中,否則任何XML保留符號都必須轉義。接下來,disable-output-escaping =「yes」屬性將取決於節點類型。如果是文本節點,則將撤消轉義,使得「& lt;」轉換爲「<」。如果它是CDATA節點,它將禁用轉義並且CDATA將按原樣輸出。在任何一種情況下,文本節點中包含的所有標籤在保留CDATA時都會被剝離(並根據禁用輸出轉義進行轉義)。因此,無論DOMSource還是Transformer(不確定誰將DOM呈現爲XML)都將在轉換之前實現對DOM文本節點的實際轉義(並保持CDATA保持不變)。因此,對於文本節點,禁用輸出轉義應該讀取撤消xml轉義這解決了我的困惑。

反正,感謝邁克爾的解釋!

2

禁用輸出轉義通常僅在轉換的輸出直接寫入串行器時纔有效。雖然XSLT規範將其描述爲對數據模型的擴展,因此在文本節點中存在與「禁止轉義該字符」的每個字符相關聯的額外位,但大多數實現不太可能允許您存儲這個模型在內存中是一棵樹,只有當樹從變換器流向串行器時才存在額外的位。 (在Saxon的實現中,不是使用每個字符的額外位,而是將一個x00字符插入從變換器傳遞到串行器的數據流中以切換開啓或關閉;這取決於x00是Java中的合法字符,而不是XML)。