2008-11-04 34 views
10

Tuyên bố từ chối trách nhiệm: sau đây là tội lỗi chống lại XML. Đó là lý do tại sao tôi đang cố gắng để thay đổi nó với XSLT :)Khoảng trắng thuộc tính lưu giữ

XML của tôi hiện trông như thế này:

<root> 
    <object name="blarg" property1="shablarg" property2="werg".../> 
    <object name="yetanotherobject" .../> 
</root> 

Vâng, tôi đang đặt tất cả các dữ liệu văn bản trong các thuộc tính. Tôi hy vọng XSLT có thể cứu tôi; Tôi muốn tiến tới một cái gì đó như thế này:

<root> 
    <object> 
     <name>blarg</name> 
     <property1>shablarg</name> 
     ... 
    </object> 
    <object> 
     ... 
    </object> 
</root> 

Tôi đã thực sự nhận được tất cả những điều này làm việc cho đến nay, ngoại trừ rằng tội lỗi của tôi đối với XML đã hơn ... đặc biệt. Một số thẻ trông giống như sau:

<object description = "This is the first line 

This is the third line. That second line full of whitespace is meaningful"/> 

Tôi đang sử dụng xsltproc trong linux, nhưng dường như không có bất kỳ tùy chọn nào để giữ khoảng trắng. Tôi đã cố gắng sử dụng xsl: preserve-space và xml: space = "preserve" để không có kết quả. Mọi tùy chọn tôi đã tìm thấy dường như áp dụng để giữ khoảng trắng trong chính các phần tử, nhưng không phải là các thuộc tính. Mỗi lần duy nhất, các thay đổi trên được thay đổi thành:

 
This is the first line This is the third line. That second line full of whitespace is meaningful 

Vì vậy, câu hỏi đặt ra là tôi có thể giữ khoảng trắng thuộc tính không?

+0

Bạn nên thay thế khoảng trắng của mình với tham chiếu thực thể cho bên trong giá trị attribe, như thay thế '' với ''. Việc chuẩn hóa giá trị thuộc tính (3.3.3) sau đó phụ thuộc vào kiểu thuộc tính mà tôi nghĩ là 'CDATA' bằng cách defatult. Tuy nhiên tôi nghĩ rằng bạn có thể ép buộc nó với ' '>' - có thể hoặc có thể không chính xác. Sau đó, nếu bạn có một XSL, bạn cần đảm bảo xử lý không gian trắng của bạn theo cách thủ công, tôi đã thực hiện tương tự như 'string-join()' và 'tokenize()'. – n611x007

+0

*** Nó có thể được thực hiện. *** Bạn có thể nhận được một ví dụ đầy đủ ([SSCCE] (http://www.sscce.org/ "Ngắn, Tự chứa, Sửa (Compilable), Ví dụ")) trong số câu trả lời của tôi cho một câu hỏi khác: http://stackoverflow.com/a/29780972/611007 (Như tôi đã giải thích ở trên, nó không phải là cách bạn cố gắng làm điều đó nhưng cuối cùng, nó sẽ hoạt động như bạn muốn.) – n611x007

+0

liên quan: https://stackoverflow.com/questions/449627/ - liên quan: https://stackoverflow.com/questions/2004386/ - liên quan: https://stackoverflow.com/questions/1289524/ – n611x007

Trả lời

5

Đây thực sự là một vấn đề phân tích cú pháp XML thô, chứ không phải thứ gì đó mà XSLT có thể giúp bạn. Phân tích cú pháp XML phải chuyển đổi các dòng mới trong giá trị thuộc tính đó thành dấu cách, theo ‘3.3.3 Phân loại giá trị thuộc tính’ trong tiêu chuẩn XML. Vì vậy, bất cứ điều gì hiện đang đọc thuộc tính mô tả của bạn và giữ các dòng mới trong đang làm sai.

Bạn có thể khôi phục các dòng mới bằng cách xử lý trước XML để thoát khỏi các dòng mới thành & # 10; các tham chiếu ký tự, miễn là bạn cũng chưa nhận được dòng mới nơi không cho phép các charref, chẳng hạn như các thẻ bên trong. Charrefs nên tồn tại dưới dạng ký tự điều khiển thông qua giá trị thuộc tính, nơi bạn có thể biến chúng thành các nút văn bản.

+1

Tôi không chắc chắn điều này sẽ làm việc. Charrefs được thay thế bằng các byte mà chúng đại diện bởi bộ xử lý XML, và do đó một charref đề cập đến một ký tự khoảng trống (như LINE FEED) sẽ được chuẩn hóa thành khoảng trắng. – ChuckB

+1

Bộ thử nghiệm DOM chuẩn và tiêu chuẩn cho biết nó hoạt động; Thực hiện của bạn Có thể thay đổi, nhưng những gì tôi đã thử nghiệm làm. – bobince

+0

@ChuckB Tôi nghĩ rằng nó phụ thuộc * cho dù bạn có thể kiểm soát bộ xử lý xml của bạn *. Tôi có thể tạo ra một đầu ra tốt với một '.xsl' hoạt động cả trong saxon và firefox. – n611x007

3

Theo Annotated XML Spec, khoảng trắng trong giá trị thuộc tính được chuẩn hóa bởi bộ xử lý XML (Xem chú thích (T) trên 3.3.3). Vì vậy, có vẻ như câu trả lời có lẽ là không.

+0

trừ khi bạn có thể kiểm soát bộ xử lý xml của mình. – n611x007

1

Như những người khác đã chỉ ra, thông số XML không cho phép bảo toàn không gian trong thuộc tính. Trong thực tế, đây là một trong số ít sự khác biệt giữa những gì bạn có thể làm với các thuộc tính và các phần tử (yếu tố chính khác là các phần tử có thể chứa các thẻ khác trong khi các thuộc tính không thể).

Bạn sẽ phải xử lý tệp bên ngoài XML trước để bảo toàn không gian.

+0

Tôi nghĩ rằng điều này là gây hiểu lầm. Nếu bạn có thể kiểm soát bộ xử lý xml của bạn, chính nó có vẻ hợp lệ và có thể để bảo vệ không gian trắng đó. Tôi có thể đạt được kết quả. – n611x007

0

Nếu bạn có thể kiểm soát bộ xử lý XML của mình, bạn có thể thực hiện.

Từ tôi other answer (trong đó có nhiều tài liệu tham khảo liên kết):

nếu bạn có một XML như

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE elemke [ 
<!ATTLIST brush wood CDATA #REQUIRED> 
]> 

<elemke> 
<brush wood="guy&#xA;threep"/> 
</elemke> 

và một XSL như

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="split"> 
    <xsl:param name="list"  select="''" /> 
    <xsl:param name="separator" select="'&#xA;'" /> 
    <xsl:if test="not($list = '' or $separator = '')"> 
    <xsl:variable name="head" select="substring-before(concat($list, $separator), $separator)" /> 
    <xsl:variable name="tail" select="substring-after($list, $separator)" /> 

    <xsl:value-of select="$head"/> 
    <br/><xsl:text>&#xA;</xsl:text> 
    <xsl:call-template name="split"> 
     <xsl:with-param name="list"  select="$tail" /> 
     <xsl:with-param name="separator" select="$separator" /> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 


<xsl:template match="brush"> 
    <html> 
    <xsl:call-template name="split"> 
    <xsl:with-param name="list" select="@wood"/> 
    </xsl:call-template> 
    </html> 
</xsl:template> 

</xsl:stylesheet> 

bạn có thể có được một html như sau:

<html>guy<br> 
    threep<br> 

</html> 

như thử nghiệm/sản xuất với một bộ xử lý như dòng saxon lệnh này:

java -jar saxon9he.jar -s:in.xml -xsl:in.xsl -o:out.html 
+0

'ATTLIST' và' DOCTYPE' ở đây thực sự không cần thiết, CDATA sẽ là 'loại thuộc tính' mặc định cho ['AttValue'] (http://www.jelks.nu/XML/xmlebnf.html#NT- AttValue) tại đây. – n611x007

+0

FYI một bài đăng ngẫu nhiên trên bộ xử lý và trình phân tích cú pháp: http://www.oxygenxml.com/archives/xsl-list/200009/msg00750.html – n611x007

+0

Tín dụng cho [Tomalak] (https://stackoverflow.com/a/2850181/ 611007) cho mẫu 'chuỗi' vì trong bộ xử lý xml đích của tôi ['tokenize'] (http://www.w3.org/TR/xpath-functions/#func-tokenize) không có sẵn. – n611x007

Các vấn đề liên quan