2009-03-14 38 views
8

Tôi viết bài này bởi vì tôi đã thực sự đánh vào tường và không thể tiếp tục. Trong cơ sở dữ liệu của tôi, tôi đã thoát HTML như sau: "<p>My name is Freddy and I was".Vấn đề thoát nhân vật XSL

Tôi muốn hiển thị nó dưới dạng HTML HOẶC loại bỏ các thẻ HTML trong mẫu XSL của tôi. Cả hai giải pháp sẽ làm việc cho tôi và tôi sẽ chọn giải pháp nhanh hơn.

Tôi đã đọc một số bài đăng trực tuyến nhưng không thể tìm thấy giải pháp. Tôi cũng đã cố gắng vô hiệu hóa-đầu ra-thoát mà không thành công. Về cơ bản có vẻ như vấn đề là một nơi nào đó trong XSL thực hiện động cơ đang thay đổi này <p> thành điều này: <p>.

Đang chuyển đổi & thành &. Nếu nó giúp, đây là mã XSL của tôi. Tôi đã thử một số kết hợp có và không có thẻ đầu ra ở trên cùng.

Mọi trợ giúp sẽ được đánh giá cao. Cảm ơn trước.

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

    <xsl:output method="html" omit-xml-declaration="yes"/> 

    <xsl:template match="DocumentElement"> 
    <div> 
     <xsl:attribute name="id">mySlides</xsl:attribute> 
     <xsl:apply-templates> 
     <xsl:with-param name="templatenumber" select="0"/> 
     </xsl:apply-templates> 
    </div> 

    <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <xsl:apply-templates> 
     <xsl:with-param name="templatenumber" select="1"/> 
     </xsl:apply-templates> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults"> 
    <xsl:param name="templatenumber">tobereplace</xsl:param> 

    <xsl:if test="$templatenumber=0"> 
     <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <div> 
      <xsl:attribute name="class">article</xsl:attribute> 
      <h2> 
      <a> 
       <xsl:attribute name="class">title</xsl:attribute> 
       <xsl:attribute name="title"><xsl:value-of select="Title"/></xsl:attribute> 
       <xsl:attribute name="href">/stories/stories-details/articletype/articleview/articleid/<xsl:value-of select="ArticleId"/>/<xsl:value-of select="SEOTitle"/>.aspx</xsl:attribute> 
       <xsl:value-of select="Title"/> 
      </a> 
      </h2> 
      <div> 
      <xsl:attribute name="style">text-indent: 25px;</xsl:attribute> 
      <xsl:attribute name="class">articlesummary</xsl:attribute> 
      <xsl:call-template name="removeHtmlTags"> 
       <xsl:with-param name="html" select="Summary" /> 
      </xsl:call-template> 
      </div> 
     </div> 
     </div> 
    </xsl:if> 
    <xsl:if test="$templatenumber=1"> 
     <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <span> 
      <xsl:attribute name="class">jFlowControl</xsl:attribute> 
      aa 
     </span> 
     </div> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="removeHtmlTags"> 
    <xsl:param name="html"/> 
    <xsl:choose> 
     <xsl:when test="contains($html, '&lt;')"> 
     <xsl:value-of select="substring-before($html, '&lt;')"/> 
     <!-- Recurse through HTML --> 
     <xsl:call-template name="removeHtmlTags"> 
      <xsl:with-param name="html" select="substring-after($html, '&gt;')"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$html"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+0

@Marcos, tôi cần một số hiểu biết giúp đỡ những gì bạn đang cố gắng làm. XSLT của bạn cho biết nó đang cố gắng xuất HTML, nhưng sau đó bạn có một mẫu cho biết bạn đang xóa các thẻ HTML. Không chắc chắn lý do tại sao bạn đang cố gắng làm điều đó. Vui lòng cung cấp thêm một số thông tin nếu bạn có thể. – Nick

+0

Để có thể nói bất cứ điều gì về vấn đề nó sẽ thực sự hữu ích khi có một ví dụ về đầu vào XML được chạy qua bảng định kiểu và hiển thị vấn đề, và cũng để biết bộ vi xử lý XSLT nào bạn đang sử dụng ... – Laurent

Trả lời

6

Bạn không nên lưu trữ HTML đã thoát trong cơ sở dữ liệu của mình. Nếu cơ sở dữ liệu của bạn chứa ký tự "<" thực, thì lệnh "disable-output-escaping" sẽ làm những gì bạn muốn.

Nếu bạn không thể thay đổi dữ liệu thì bạn sẽ phải hủy cảnh báo dữ liệu trước khi thực hiện phép biến đổi.

+0

Thks! Tôi đã có cái nhìn sâu sắc này ngay bây giờ: Thay vì cố gắng để unescape

+0

+1. Tôi ghét khi mọi người lưu trữ các cấu trúc như thế này trong cơ sở dữ liệu. Đó là một cơn ác mộng quản lý. –

18

Có trụ sở tại giả định rằng bạn có chuỗi HTML này,

<p>My name is Freddy &amp; I was 

sau đó nếu bạn thoát khỏi nó và lưu nó trong một cơ sở dữ liệu nó sẽ trở thành này:

&lt;p&gt;My name is Freddy &amp;amp; I was 

Do , nếu bạn truy xuất nó dưới dạng XML (mà không hủy định dạng trước), kết quả sẽ là này:

&amp;lt;p&amp;gt;My name is Freddy &amp;amp;amp; I was 

<xsl:value-of select="." disable-output-escaping="yes" /> sẽ tạo ra:

&lt;p&gt;My name is Freddy &amp;amp; I was 

Bạn đang nhận được chính xác những điều tương tự mà bạn có trong cơ sở dữ liệu của bạn, nhưng tất nhiên bạn nhìn thấy các thẻ HTML trong đầu ra.Vì vậy, những gì bạn cần là một cơ chế mà không được thay thế chuỗi sau:

  • "&amp;lt;" với "&lt;" (thay đổi một cách hiệu quả &lt;-< trong ouput không thoát)
  • "&amp;gt;" với "&gt;" (thay đổi một cách hiệu quả &gt;-> trong ouput không thoát)
  • "&amp;quot;" với "&quot;" (thay đổi có hiệu quả &quot; thành " trong ouput chưa cắt)
  • "&amp;amp;" với "&amp;" (thay đổi một cách hiệu quả &amp;-& trong ouput unescaped)

Từ XSL của bạn tôi đã suy ra XML kiểm tra đầu vào sau:

<DocumentElement> 
    <QueryResults> 
    <Title>Article 1</Title> 
    <ArticleId>1</ArticleId> 
    <SEOTitle>Article_1</SEOTitle> 
    <Summary>&amp;lt;p&amp;gt;Article 1 summary &amp;amp;amp; description.&amp;lt;/p&amp;gt;</Summary> 
    </QueryResults> 
    <QueryResults> 
    <Title>Article 2</Title> 
    <ArticleId>2</ArticleId> 
    <SEOTitle>Article_2</SEOTitle> 
    <Summary>&amp;lt;p&amp;gt;Article 2 summary &amp;amp;amp; description.&amp;lt;/p&amp;gt;</Summary> 
    </QueryResults> 
</DocumentElement> 

Tôi đã thay đổi kiểu bạn cung cấp và thực hiện như một cơ chế thay thế. Nếu bạn áp dụng những điều sau XSLT 1.0 mẫu với nó:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my:namespace" 
    exclude-result-prefixes="my" 
> 

    <xsl:output method="html" omit-xml-declaration="yes"/> 

    <my:unescape> 
    <my:char literal="&lt;" escaped="&amp;lt;" /> 
    <my:char literal="&gt;" escaped="&amp;gt;" /> 
    <my:char literal="&quot;" escaped="&amp;quot;" /> 
    <my:char literal="&amp;" escaped="&amp;amp;" /> 
    </my:unescape> 

    <xsl:template match="DocumentElement"> 
    <div id="mySlides"> 
     <xsl:apply-templates mode="slides" /> 
    </div> 
    <div id="myController"> 
     <xsl:apply-templates mode="controller" /> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults" mode="slides"> 
    <div class="article"> 
     <h2> 
     <a class="title" title="{Title}" href="{concat('/stories/stories-details/articletype/articleview/articleid/', ArticleId, '/', SEOTitle, '.aspx')}"> 
      <xsl:value-of select="Title"/> 
     </a> 
     </h2> 
     <div class="articlesummary" style="text-indent: 25px;"> 
     <xsl:apply-templates select="document('')/*/my:unescape/my:char[1]"> 
      <xsl:with-param name="html" select="Summary" /> 
     </xsl:apply-templates> 
     </div> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults" mode="controller"> 
    <span class="jFlowControl"> 
     <xsl:text>aa </xsl:text> 
     <xsl:value-of select="Title" /> 
    </span> 
    </xsl:template> 

    <xsl:template match="my:char"> 
    <xsl:param name="html" /> 
    <xsl:variable name="intermediate"> 
     <xsl:choose> 
     <xsl:when test="following-sibling::my:char"> 
      <xsl:apply-templates select="following-sibling::my:char[1]"> 
      <xsl:with-param name="html" select="$html" /> 
      </xsl:apply-templates> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$html" disable-output-escaping="yes" /> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:call-template name="unescape"> 
     <xsl:with-param name="html" select="$intermediate" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="unescape"> 
    <xsl:param name="html" /> 
    <xsl:choose> 
     <xsl:when test="contains($html, @escaped)"> 
     <xsl:value-of select="substring-before($html, @escaped)" disable-output-escaping="yes"/> 
     <xsl:value-of select="@literal" disable-output-escaping="yes" /> 
     <xsl:call-template name="unescape"> 
      <xsl:with-param name="html" select="substring-after($html, @escaped)"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$html" disable-output-escaping="yes"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

Rồi HTML sản lượng này được sản xuất:

<div id="mySlides"> 
    <div class="article"> 
    <h2> 
     <a class="title" title="Article 1" href="/stories/stories-details/articletype/articleview/articleid/1/Article_1.aspx">Article 1</a> 
    </h2> 
    <div class="articlesummary" style="text-indent: 25px;"> 
     <p>Article 1 summary &amp; description.</p> 
    </div> 
    </div> 
    <div class="article"> 
    <h2> 
     <a class="title" title="Article 2" href="/stories/stories-details/articletype/articleview/articleid/2/Article_2.aspx">Article 2</a> 
    </h2> 
    <div class="articlesummary" style="text-indent: 25px;"> 
     <p>Article 2 summary &amp; description.</p> 
    </div> 
    </div> 
</div> 
<div id="myController"> 
    <span class="jFlowControl">aa Article 1</span> 
    <span class="jFlowControl">aa Article 2</span> 
</div> 

Note

  • việc sử dụng một không gian tên tạm thời và các yếu tố nhúng (<my:unescape>) để tạo danh sách các ký tự để thay thế
  • việc sử dụng đệ quy để mô phỏng sự thay thế lặp lại của tất cả các chara bị ảnh hưởng cters trong đầu vào
  • việc sử dụng bối cảnh tiềm ẩn trong unescape mẫu để vận chuyển các thông tin mà nhân vật là phải được thay thế vào lúc

Hơn nữa lưu ý:

  • việc sử dụng các chế độ mẫu để có được đầu ra khác nhau cho cùng một đầu vào (điều này thay thế tham số templatenumber)
  • hầu hết thời gian của bạn không cần đến các yếu tố <xsl:attribute>. Họ có thể yên tâm được thay thế bằng ký hiệu inline (attributename="{attributevalue}")
  • việc sử dụng các concat() chức năng để tạo ra các URL

Nói chung, đó là một ý tưởng tồi để lưu trữ thoát HTML trong một cơ sở dữ liệu (hơn nói chung: Đó là một ý tưởng tồi để lưu trữ HTML trong cơ sở dữ liệu.). Bạn đặt mình lên để có được tất cả các loại vấn đề, đây là một trong số họ. Nếu bạn không thể thay đổi thiết lập này, tôi hy vọng rằng giải pháp sẽ giúp bạn.

Tôi không thể đảm bảo rằng nó hoạt động đúng trong mọi tình huống và nó có thể mở lỗ hổng bảo mật (nghĩ XSS), nhưng giải quyết vấn đề này không phải là một phần của câu hỏi. Trong mọi trường hợp, hãy xem xét chính mình cảnh báo.

Tôi cần nghỉ ngơi ngay bây giờ.;-)

+0

Giải thích tuyệt vời! –

+0

Cảm ơn, tôi đã có cùng một vấn đề chính xác :) +1 cho câu trả lời tuyệt vời của bạn. – EinLama

1

Đó là một ý tưởng tồi để lưu trữ HTML trong một cơ sở dữ liệu

gì? Làm thế nào bạn có nghĩa vụ để lưu trữ nó sau đó? Trong một tài liệu XML, bạn vẫn phải sử dụng XSLT? Là một nhà phát triển web, chúng tôi đã luôn sử dụng cơ sở dữ liệu SQL để lưu trữ dữ liệu HTML do người dùng xác định. Không có gì sai với phương pháp đó miễn là nó được khử trùng đúng cách cho mục đích của bạn.

+0

Nó không phải là thực hành tốt. Nếu bạn đã đi với nó, bạn chỉ đơn giản là không làm việc trên một hệ thống đã có quy mô. – itsbruce

+0

Ý tưởng tồi hoặc không, gần như toàn bộ trang web được điều khiển bởi HTML lưu trữ cơ sở dữ liệu những ngày này. WordPress là một ví dụ rõ ràng. –

+0

Có thể ít phiền toái khi sử dụng MarkDown thay vì đánh dấu HTML. Dù bằng cách nào, có ** là ** trường hợp sử dụng mà bạn muốn một số loại đánh dấu được lưu trữ trong cơ sở dữ liệu. – CoDEmanX

2

Thêm dòng này để stylesheet của bạn

<xsl:output method="html" indent="yes" version="4.0"/> 
Các vấn đề liên quan