2012-06-21 25 views
5

Tôi đang tạo đối tượng Tài liệu W3C bằng cách sử dụng giá trị Chuỗi. Khi tôi đã tạo đối tượng Document, tôi muốn thêm một không gian tên vào phần tử gốc của tài liệu này. Đây là mã hiện tại của tôi:Thêm không gian tên vào tài liệu XML đã được tạo

Document document = builder.parse(new InputSource(new StringReader(xmlString))); 
document.getDocumentElement().setAttributeNS("http://com", "xmlns:ns2", "Test"); 
document.setPrefix("ns2"); 
TransformerFactory tranFactory = TransformerFactory.newInstance(); 
Transformer aTransformer = tranFactory.newTransformer(); 
Source src = new DOMSource(document); 
Result dest = new StreamResult(new File("c:\\xmlFileName.xml")); 
aTransformer.transform(src, dest); 

gì tôi sử dụng như là đầu vào:

<product> 
    <arg0>DDDDDD</arg0> 
    <arg1>DDDD</arg1> 
</product> 

gì đầu ra sẽ giống như thế:

<ns2:product xmlns:ns2="http://com"> 
    <arg0>DDDDDD</arg0> 
    <arg1>DDDD</arg1> 
</ns2:product> 

tôi cần phải thêm giá trị tiền tố và namespace cũng để chuỗi xml đầu vào. Nếu tôi thử mã ở trên, tôi nhận được ngoại lệ này:

NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. 

Đánh giá cao sự trợ giúp của bạn!

+1

là 'bạn builder' namespace-aware? 'builder.isNamespaceAware()' – rolve

Trả lời

19

Vì không có cách dễ dàng để đổi tên phần tử gốc, chúng tôi sẽ phải thay thế bằng phần tử có không gian tên và thuộc tính chính xác, sau đó sao chép tất cả các tệp gốc vào đó. Việc buộc khai báo không gian tên là không cần thiết vì bằng cách cho phần tử đúng không gian tên (URI) và thiết lập tiền tố, khai báo sẽ tự động.

Thay setAttributesetPrefix với điều này (dòng 2,3)

String namespace = "http://com"; 
String prefix = "ns2"; 
// Upgrade the DOM level 1 to level 2 with the correct namespace 
Element originalDocumentElement = document.getDocumentElement(); 
Element newDocumentElement = document.createElementNS(namespace, originalDocumentElement.getNodeName()); 
// Set the desired namespace and prefix 
newDocumentElement.setPrefix(prefix); 
// Copy all children 
NodeList list = originalDocumentElement.getChildNodes(); 
while(list.getLength()!=0) { 
    newDocumentElement.appendChild(list.item(0)); 
} 
// Replace the original element 
document.replaceChild(newDocumentElement, originalDocumentElement); 

Trong đoạn mã ban đầu tác giả đã cố gắng để khai báo một namespace yếu tố như thế này:

.setAttributeNS("http://com", "xmlns:ns2", "Test"); 

Tham số đầu tiên là không gian tên của thuộc tính và vì đó là thuộc tính không gian tên nên cần có URI http://www.w3.org/2000/xmlns/. Không gian tên được khai báo phải được nhập vào thông số thứ 3

.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns2", "http://com"); 
+0

Cảm ơn rất nhiều! Nó thực sự đã giúp tôi, trong trường hợp của tôi không gian tên chưa bao giờ được bao gồm trong tính toán tiêu hóa, bởi vì tôi đã thêm nó như là một thuộc tính thường xuyên thay vì thêm nó như là một không gian tên thực. +1 – Springrbua

+0

Có vẻ cách tiếp cận này không thể thêm cùng một không gian tên cho phần tử con, vì vậy tôi sử dụng phương pháp này, sau đó tạo chuỗi XML từ tài liệu và phân tích chuỗi XML được tạo lại. – wangf

0

Phương pháp tiếp cận này cũng phù hợp với tôi, nhưng có lẽ không nên sử dụng trong trường hợp quan trọng.

  1. Thêm không gian tên để ghi lại phần tử gốc làm thuộc tính.
  2. Chuyển đổi tài liệu thành chuỗi XML. Mục đích của bước này là làm cho phần tử con trong chuỗi XML thừa kế không gian tên phần tử cha.
  3. Bây giờ chuỗi xml có không gian tên.
  4. Bạn có thể sử dụng chuỗi XML để xây dựng một tài liệu một lần nữa hoặc sử dụng cho JAXB unmarshal vv

private static String addNamespaceToXml(InputStream in) 
     throws ParserConfigurationException, SAXException, IOException, 
     TransformerException { 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    /* 
    * Must not namespace aware, otherwise the generated XML string will 
    * have wrong namespace 
    */ 
    // dbf.setNamespaceAware(true); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document document = db.parse(in); 
    Element documentElement = document.getDocumentElement(); 
    // Add name space to root element as attribute 
    documentElement.setAttribute("xmlns", "http://you_name_space"); 
    String xml = transformXmlNodeToXmlString(documentElement); 
    return xml; 
} 

private static String transformXmlNodeToXmlString(Node node) 
     throws TransformerException { 
    TransformerFactory transFactory = TransformerFactory.newInstance(); 
    Transformer transformer = transFactory.newTransformer(); 
    StringWriter buffer = new StringWriter(); 
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
    transformer.transform(new DOMSource(node), new StreamResult(buffer)); 
    String xml = buffer.toString(); 
    return xml; 
} 
Các vấn đề liên quan