2013-03-01 11 views
5

Tôi đang cố gắng sử dụng groovy để chỉ cần thêm nút vào một vị trí cụ thể. schema nguồn của tôi trông giống như Groovy: cách phân tích cú pháp xml và bảo toàn không gian tên và lược đồ

<s1:RootNode 
    xmlns:s1="http://localhost/s1schema" 
    xmlns:s2="http://localhost/s2schema" 
    xsi:schemaLocation="http://localhost/s1schema s1schema.xsd 
    http://localhost/s2schema s2schema.xsd"> 
<s1:aParentNode> 
    <s2:targetNode> 
    <s2:childnode1 /> 
    <s2:childnode2 /> 
    <s2:childnode3 /> 
    <s2:childnode4 /> 
</s2:targetNode> 
</s1:aParentNode> 
</s1:RootNode> 

Tôi muốn chỉ cần thêm một inline nút con mới với những người khác để làm cho sản lượng

<s1:RootNode 
    xmlns:s1="http://localhost/s1schema" 
    xmlns:s2="http://localhost/s2schema" 
    xsi:schemaLocation="http://localhost/s1schema s1schema.xsd 
    http://localhost/s2schema s2schema.xsd"> 
<s1:aParentNode>  
    <s2:targetNode> 
    <s2:childnode1 /> 
    <s2:childnode2 /> 
    <s2:childnode3 /> 
    <s2:childnode4 /> 
    <s2:childnode5 >value</s2:childnode5> 
    </s2:targetNode> 
    </s1:aParentNode> 
</s1:RootNode> 

Để làm điều này tôi đã kịch bản này

sau đơn giản groovy

def data = 'value' 
def root = new XmlSlurper(false,true).parseText(sourceXML) 
     root.'aParentNode'.'topNode'.appendNode{ 
      's2:childnode5' data 
     } 
groovy.xml.XmlUtil.serialize(root); 

tuy nhiên khi tôi thực hiện điều này, không gian tên và lược đồ được áp dụng cho nút gốc sẽ bị xóa. và không gian tên, nhưng không phải là vị trí lược đồ đang được thêm vào mỗi nút con.

điều này đang gây ra sự cố xác thực ở hạ lưu.

Tôi chỉ cần xử lý xml này như thế nào. thực hiện không có xác nhận và để lại xml như là và thêm một nút duy nhất của một không gian tên tôi chỉ định? Một lưu ý: chúng tôi xử lý nhiều thư và tôi sẽ không biết trước không gian tên ngoài nhất (s1 trong ví dụ trên) nhưng ngay cả với điều đó, tôi thực sự chỉ cần tìm kiếm một kỹ thuật là "dumber" xử lý xml

Cảm ơn!

Trả lời

2

Trước tiên, tôi phải thêm xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" để xác định không gian tên xsi của bạn. Không có nó, tôi sẽ nhận được SAXParseException cho tiền tố xsi không liên kết.

Ngoài ra, tôi đã tham khảo ý kiến ​​question về việc thêm thành công nút xml không gian tên vào tài liệu hiện có.

Cuối cùng, chúng tôi đã phải sử dụng StreamingMarkupBuilder để làm việc xung quanh việc di chuyển các không gian tên. Về cơ bản, theo mặc định, bộ nối tiếp di chuyển các vùng tên được tham chiếu đến nút đầu tiên thực sự sử dụng vùng tên. Trong trường hợp của bạn, nó đã chuyển thuộc tính không gian tên s2 của bạn sang thẻ "targetNode". Đoạn mã sau tạo ra các kết quả mà bạn muốn, nhưng bạn vẫn sẽ phải biết các không gian tên đúng để sử dụng để khởi tạo StreamingMarkupBuilder.

def root = new XmlSlurper(false, true).parseText(sourceXML) 
def data = '<s2:childnode5 xmlns:s2="http://localhost/s2schema">value</s2:childnode5>' 
def xmlFragment = new XmlSlurper(false, true).parseText(data) 
root.'aParentNode'.'targetNode'.appendNode(xmlFragment); 

def outputBuilder = new StreamingMarkupBuilder() 
String result = XmlUtil.serialize(outputBuilder.bind { 
    mkp.declareNamespace('s1':"http://localhost/s1schema") 
    mkp.declareNamespace('s2':"http://localhost/s2schema") 
    mkp.yield root } 
) 
+0

Câu hỏi này cũng đề cập đến một số vấn đề tương tự: http://stackoverflow.com/questions/227447/how-do-i-print-a-groovy-node-with-namespace-preserved – purgatory101

+0

Cảm ơn. Tôi đã vấp ngã trên một giải pháp như thế này, vấn đề duy nhất tôi có là tôi sẽ không biết schemata nào được định nghĩa hoặc cần phải được định nghĩa trước khi xử lý vì vậy tôi sẽ không thể 'mkp.declareNamespace (..)' Hơn nữa, chúng ta cần có khả năng xử lý các thay đổi đối với lược đồ mà không cần thay đổi thành phần này. Vì vậy, câu trả lời duy nhất của tôi sẽ là một cái gì đó định nghĩa các sơ đồ này như một số bản đồ hoặc phân tích chúng từ xml trước khi thực hiện công việc.Trong khi đó là nhiều dòng mã hơn, nó dường như rõ ràng hơn những gì đang xảy ra bằng cách sử dụng DOM để phân tích cú pháp xml trong java – Beta033

0

XMLSlurper (hoặc XMLParser) không xử lý không gian tên nếu bạn đặt tham số thứ hai của các nhà xây dựng:

XmlSlurper (boolean validating, boolean namespaceAware) 

false:

def root = new XmlSlurper(false, false).parseText(sourceXML) 

Nếu không có thiết namespaceAware false, tôi cũng phải đối mặt với bahavior lạ của trình phân tích cú pháp. Sau khi thiết lập thành false, nó rời khỏi XML như là, không có thay đổi không gian tên.