2015-10-06 7 views
6

मेरे पास एक HTML दस्तावेज़ है जिसमें &lt; और &gt; कुछ विशेषताओं में हो सकता है। मैं इसे निकालने की कोशिश कर रहा हूं और इसे एक्सएसएलटी के माध्यम से चला रहा हूं, लेकिन एक्सएसएलटी इंजन त्रुटियों ने मुझे बताया कि < एक विशेषता के अंदर मान्य नहीं है।आंतरिक HTML unencodes < गुणों में

मैं कुछ खुदाई किया था, और देखा कि वह ठीक स्रोत दस्तावेज़ में बच रहा है, लेकिन जब यह innerHTML के माध्यम से डोम में लोड किया जाता, डोम unencoding गुण है। आश्चर्यजनक रूप से, यह &lt; और &gt; के लिए करता है, लेकिन कुछ अन्य &amp; जैसे नहीं।

यहाँ एक सरल उदाहरण है:

var div = document.createElement('DIV'); 
 
div.innerHTML = '<div asdf="&lt;50" fdsa="&amp;50"></div>'; 
 
console.log(div.innerHTML)

मैं यह सोचते हैं रहा हूँ डोम कार्यान्वयन फैसला किया है कि जो HTML गुण XML गुणधर्मों तुलना में कम सख्त हो सकता है, और यह कि "के रूप में काम कर रहा है इरादा "। मेरा सवाल है, क्या मैं कुछ भयानक रेगेक्स प्रतिस्थापन के बिना इस पर काम कर सकता हूं?

+0

@Abel, मैं सिर्फ मैं कहाँ लगता है "समस्या" हो रहा है करने के लिए नीचे कम करने के लिए प्रयास किया। स्रोत दस्तावेज़ एक्सएमएल है, जिसे मैं '.html() 'के साथ डालने से पहले ब्राउज़र XSLT के माध्यम से चलाता हूं। बाद में मैं एक्सएमएल को वापस पाने के लिए इसे उलटा प्रक्रिया के माध्यम से ले जाता हूं। मुझे बस यह अजीब लगता है कि डोम * इस चरित्र को अनदेखा कर रहा है (और दूसरों को नहीं)। – murrayju

+0

मैं स्रोत एक्सएमएल को संशोधित नहीं कर सकता, और अंत में आउटपुट में एक ही सामग्री को संरक्षित करने की आवश्यकता है।मैं बीच में जो भी परिवर्तन आवश्यक हो सकता हूं, लेकिन कुछ रेगेक्स प्रतिस्थापन से बेहतर करने के लिए एक तरीका तलाश रहा हूं। विशेष रूप से चरित्र पर विचार करना '<' है, जिसे दस्तावेज़ भरा हुआ है। – murrayju

+0

@ अब्बल मेरा एकमात्र लक्ष्य यह है कि इसे डीओएम से वापस ले जाना उसी तरह से (जैसा कि < ') था। मैं इसे '.text (स्ट्रिंग)' के साथ डाल रहा हूं और इसे '.text()' के साथ प्राप्त कर रहा हूं। इस राउंड-ट्रिप के साथ मेरी समस्या यह है कि इनपुट आउटपुट के बराबर नहीं है (केवल इस मामले में)। – murrayju

उत्तर

0

मेरे लिए सबसे अच्छा काम करना समाप्त हुआ था आने वाले दस्तावेज़ पर एक्सएसएलटी का उपयोग करके इन्हें दोबारा बचाना था (और आउटगोइंग दस्तावेज़ पर इसे उलटाना)।

तो &lt; एक विशेषता में &amp;lt; बन जाता है। सुझाव के लिए @Abel के लिए धन्यवाद।

यहाँ, XSLT मैं जोड़ा है मामले में अन्य लोगों ने इसे उपयोगी पाते:

पहले XSLT 1.0 में स्ट्रिंग प्रतिस्थापन करने के लिए एक टेम्पलेट है। यदि आप एक्सएसएलटी 2.0 का उपयोग कर सकते हैं, तो आप इसके बजाय निर्मित replace का उपयोग कर सकते हैं।

<!-- xml -> html --> 
<xsl:template name="replace-html-codes"> 
    <xsl:param name="text"/> 
    <xsl:variable name="lt"> 
     <xsl:call-template name="string-replace-all"> 
      <xsl:with-param name="text" select="$text"/> 
      <xsl:with-param name="replace" select="'&lt;'"/> 
      <xsl:with-param name="by" select="'&amp;lt;'"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:variable name="gt"> 
     <xsl:call-template name="string-replace-all"> 
      <xsl:with-param name="text" select="$lt"/> 
      <xsl:with-param name="replace" select="'&gt;'"/> 
      <xsl:with-param name="by" select="'&amp;gt;'"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:value-of select="$gt"/> 
</xsl:template> 

<!-- html -> xml --> 
<xsl:template name="restore-html-codes"> 
    <xsl:param name="text"/> 
    <xsl:variable name="lt"> 
     <xsl:call-template name="string-replace-all"> 
      <xsl:with-param name="text" select="$text"/> 
      <xsl:with-param name="replace" select="'&amp;lt;'"/> 
      <xsl:with-param name="by" select="'&lt;'"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:variable name="gt"> 
     <xsl:call-template name="string-replace-all"> 
      <xsl:with-param name="text" select="$lt"/> 
      <xsl:with-param name="replace" select="'&amp;gt;'"/> 
      <xsl:with-param name="by" select="'&gt;'"/> 
     </xsl:call-template> 
    </xsl:variable> 
    <xsl:value-of select="$gt"/> 
</xsl:template> 

XSLT ज्यादातर एक पास के माध्यम से है:

<xsl:template name="string-replace-all"> 
    <xsl:param name="text"/> 
    <xsl:param name="replace"/> 
    <xsl:param name="by"/> 
    <xsl:choose> 
     <xsl:when test="contains($text, $replace)"> 
      <xsl:value-of select="substring-before($text,$replace)"/> 
      <xsl:value-of select="$by"/> 
      <xsl:call-template name="string-replace-all"> 
       <xsl:with-param name="text" select="substring-after($text,$replace)"/> 
       <xsl:with-param name="replace" select="$replace"/> 
       <xsl:with-param name="by" select="$by"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

अगला कि विशिष्ट प्रतिस्थापन है कि मैं की आवश्यकता है टेम्पलेट है। मैं तो बस जब नकल विशेषताओं का उचित टेम्पलेट फोन: मैं jQuery के `.html()` का उपयोग कर रहा

<xsl:template match="@*"> 
    <xsl:attribute name="data-{local-name()}"> 
     <xsl:call-template name="replace-html-codes"> 
      <xsl:with-param name="text" select="."/> 
     </xsl:call-template> 
    </xsl:attribute> 
</xsl:template> 

<!-- copy all nodes --> 
<xsl:template match="node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
0

मुझे यकीन नहीं है कि यह वही है जो आप देख रहे हैं लेकिन एक नज़र डालें।

var div1 = document.createElement('DIV'); 
var div2 = document.createElement('DIV'); 
div1.setAttribute('asdf','&lt;50'); 
div1.setAttribute('fdsa','&amp;50'); 
div2.appendChild(div1); 
console.log(div2.innerHTML.replace(/&amp;/g, '&')); 
+0

मैं यह देखने में असफल रहा कि यह प्रश्नों के उत्तर से बचने वाले प्रश्नों के साथ कैसे जवाब देता है ... और शायद आप नहीं चाहते हैं * प्रत्येक * एम्पर्सेंड बदल दिया गया ... – Abel

+0

दरअसल यह < और & से & लेफ्टिनेंट परिवर्तित करता है; और & amp; क्रमशः। प्रतिस्थापन फ़ंक्शन इसे वापस अपने मूल प्रारूप में बदल देता है। – Sumesh

+0

सटीक रूप से मेरा बिंदु। '& 'को प्रतिस्थापित नहीं किया जाना चाहिए,' < 'केवल तभी बदला जाना चाहिए यदि यह किसी संपत्ति के मान का हिस्सा है जैसे स्ट्रिंग को एक्सएमएल के रूप में व्याख्या किया गया था। यह अन्य घटनाओं (टेक्स्ट नोड्स, टिप्पणी नोड्स, प्रसंस्करण निर्देश, सीडीएटी अनुभागों को प्रतिस्थापित नहीं करना चाहिए, हालांकि इनमें से कुछ HTML में दुर्लभ हैं)। – Abel

2

XmlSerializer का प्रयास करें:

var div = document.getElementById('d1'); 
 

 
var pre = document.createElement('pre'); 
 
pre.textContent = div.outerHTML; 
 
document.body.appendChild(pre); 
 

 
pre = document.createElement('pre'); 
 
pre.textContent = new XMLSerializer().serializeToString(div); 
 
document.body.appendChild(pre);
<div id="d1" data-foo="a &lt; b &amp;&amp; b &gt; c">This is a test</div>

आप (कम से कम यहाँ Firefox के साथ एक परीक्षण में) XSLT एक्सएचटीएमएल नाम स्थान XmlSerializer आवेषण के खाते में लेने के लिए अनुकूल करने के लिए आवश्यकता हो सकती है।

+0

यह मेरी इच्छा के करीब है, लेकिन यह सभी ब्राउज़रों में काम नहीं करता है (IE8 में 'XMLSerializer' नहीं है) – murrayju

+0

@murrayju, [XML Serializer पर यह प्रश्न देखें] (http://stackoverflow.com/questions/4916327/जावास्क्रिप्ट-प्रतिस्थापन-के लिए-xmlserializer-serializetostring), अगर आपको <3% उपयोगकर्ता शेयर के साथ (पुराने) ब्राउज़र का समर्थन करना है, तो आप कर सकते हैं, और इस मामले में बस '.xml' का उपयोग करें। मुझे लगता है कि मार्टिन होननेन द्वारा यह समाधान उत्कृष्ट है :)। – Abel

+0

@Abel, मुझे नहीं लगता कि आईई या अन्यत्र एचटीएमएल डोम नोड्स के लिए 'xml' प्रॉपर्टी लागू की गई है, यह केवल एमएसएक्सएमएल डोम नोड्स के लिए मौजूद है। –

संबंधित मुद्दे