2009-09-23 13 views
36

मैं एक छोटी संपर्क सूची स्टोर करने के लिए एक्सएमएल का उपयोग कर रहा हूं और एक एक्सएसएल टेम्पलेट लिखने की कोशिश कर रहा हूं जो इसे एक CSV फ़ाइल में बदल देगा। मेरे पास जो समस्या है वह आउटपुट में व्हाइटस्पेस के साथ है।एक्सएसएलटी - टेम्पलेट से व्हाइटस्पेस हटाएं

उत्पादन:

Friend, John, Smith, Home, 
     123 test, 
     Sebastopol, 
     California, 
     12345, 
    Home 1-800-123-4567, Personal [email protected] 

मैं दांतेदार/दूरी पर दोनों स्रोत एक्सएमएल फ़ाइल और संबद्ध XSL टेम्पलेट यह आसान पढ़ सकते हैं और विकसित करने के लिए बनाने के लिए है, लेकिन है कि सभी अतिरिक्त सफेद स्थान उत्पादन में ही हो रही है । एक्सएमएल के पास नोड्स के अंदर अतिरिक्त सफेद जगह नहीं है, बस प्रारूपण के लिए उनके बाहर, और यह एक्सएसएलटी के लिए भी जाता है।

सीएसवी फ़ाइल वैध होने के लिए, प्रत्येक प्रविष्टि को अपनी लाइन पर होना चाहिए, टूटना नहीं है। एक्सएमएल और एक्सएसएलटी से सभी अतिरिक्त सफेद जगहों को अलग करने के अलावा (उन्हें कोड की केवल एक लंबी लाइन बनाना), आउटपुट में व्हाइटस्पेस से छुटकारा पाने का कोई और तरीका है?

संपादित करें: यहाँ

<PHONEBOOK> 
    <LISTING> 
     <FIRST>John</FIRST> 
     <LAST>Smith</LAST> 
     <ADDRESS TYPE="Home"> 
      <STREET>123 test</STREET> 
      <CITY>Sebastopol</CITY> 
      <STATE>California</STATE> 
      <ZIP>12345</ZIP> 
     </ADDRESS> 
     <PHONE>1-800-123-4567</PHONE> 
     <EMAIL>[email protected]</EMAIL> 
     <RELATION>Friend</RELATION> 
    </LISTING> 
</PHONEBOOK> 

और XSLT है: यहां एक छोटा एक्सएमएल नमूना है

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" /> 

<xsl:template match="/"> 
    <xsl:for-each select="//LISTING"> 
    <xsl:value-of select="RELATION" /><xsl:text>, </xsl:text> 
    <xsl:value-of select="FIRST" /><xsl:text>, </xsl:text> 
    <xsl:value-of select="LAST" /><xsl:text>, </xsl:text> 

    <xsl:if test="ADDRESS"> 
    <xsl:for-each select="ADDRESS"> 
     <xsl:choose> 
     <xsl:when test="@TYPE"> 
     <xsl:value-of select="@TYPE" />, 
     </xsl:when> 
      <xsl:otherwise> 
      <xsl:text>Home </xsl:text> 
      </xsl:otherwise> 
     </xsl:choose> 
     <xsl:value-of select="STREET" />, 
     <xsl:value-of select="CITY" />, 
     <xsl:value-of select="STATE" />, 
     <xsl:value-of select="ZIP" />, 
    </xsl:for-each> 
    </xsl:if> 

    <xsl:for-each select="PHONE"> 
     <xsl:choose> 
     <xsl:when test="@TYPE"> 
     <xsl:value-of select="@TYPE" /> 
     </xsl:when> 
     <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise> 
     </xsl:choose> 
    <xsl:value-of select="." /><xsl:text >, </xsl:text> 
    </xsl:for-each> 

    <xsl:if test="EMAIL"> 
    <xsl:for-each select="EMAIL"> 
     <xsl:choose> 
     <xsl:when test="@TYPE"> 
     <xsl:value-of select="@TYPE" /><xsl:text > </xsl:text> 
     </xsl:when> 
     <xsl:otherwise><xsl:text >Personal </xsl:text></xsl:otherwise> 
     </xsl:choose> 
     <xsl:value-of select="." /><xsl:text >, </xsl:text> 
    </xsl:for-each> 
    </xsl:if> 
    <xsl:text>&#10;&#13;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 
+4

आप प्रत्येक '' पर 'अक्षम-आउटपुट-एस्केपिंग' का उपयोग क्यों करते हैं? आपको ' 'के लिए इसकी आवश्यकता नहीं है। एक्सएसएलटी 1.0 spec से: "टेक्स्ट आउटपुट विधि अक्षम-आउटपुट-एस्केपिंग विशेषता को अनदेखा करती है, क्योंकि यह कोई आउटपुट एस्केपिंग नहीं करती है।" –

उत्तर

74

एक्सएसएलटी में, सफेद-स्थान डिफ़ॉल्ट रूप से संरक्षित है, क्योंकि यह बहुत अच्छी तरह से प्रासंगिक डेटा हो सकता है।

आउटपुट में अवांछित सफेद-स्थान को रोकने का सबसे अच्छा तरीका यह है कि इसे पहले स्थान पर न बनाएं।ऐसा मत करो:

<xsl:template match="foo"> 
    foo 
</xsl:template> 

क्योंकि उस "\n··foo\n" है, देखने के प्रोसेसर के दृष्टिकोण से। बल्कि

<xsl:template match="foo"> 
    <xsl:text>foo</xsl:text> 
</xsl:template> 

स्टाइलशीट में व्हाइट-स्पेस जब तक यह XML तत्वों केवल के बीच होता है पर ध्यान नहीं दिया जाता है। सीधे शब्दों में कहें: अपने एक्सएसएलटी कोड में कहीं भी "नग्न" टेक्स्ट का उपयोग न करें, हमेशा इसे तत्व में संलग्न करें।

इसके अलावा, एक unspecific का उपयोग कर:

<xsl:apply-templates /> 

समस्याग्रस्त है, क्योंकि पाठ के लिए डिफ़ॉल्ट XSLT नियम नोड कहते हैं, "उत्पादन करने के लिए उन्हें कॉपी"। यह "व्हाइट-स्पेस-केवल" नोड्स पर भी लागू होता है। उदाहरण के लिए:

  1. "\n··" (<xml> सही होने के बाद)
  2. "·value·"
  3. "\n" (दाएं </xml> से पहले)

कि बचने के लिए:

<xml> 
    <data> value </data> 
</xml> 

तीन पाठ नोड्स शामिल # 1 और # 3 आउटपुट में घुसपैठ (जो

<xsl:template match="text()" /> 

सभी पाठ नोड्स अब म्यूट कर दिया जाए और पाठ उत्पादन स्पष्ट रूप से बनाया जाना चाहिए: है अवांछित रिक्त स्थान के लिए सबसे आम कारण है), तो आपको एक खाली टेम्पलेट की घोषणा के द्वारा पाठ नोड्स के लिए डिफ़ॉल्ट नियम ओवरराइड कर सकते हैं

<xsl:value-of select="data" /> 

एक मूल्य से सफेद-अंतरिक्ष निकालने के लिए आपको normalize-space() XSLT समारोह इस्तेमाल कर सकते हैं:

<xsl:value-of select="normalize-space(data)" /> 

लेकिन सावधान, क्योंकि समारोह किसी भी whi को सामान्य स्ट्रिंग में पाए गए टी-स्पेस, उदा। "·value··1·""value·1" बन जाएगा।

इसके अतिरिक्त आप <xsl:strip-space> और <xsl:preserve-space> तत्वों का उपयोग कर सकते हैं, हालांकि आमतौर पर यह आवश्यक नहीं है (और व्यक्तिगत रूप से, मैं ऊपर बताए अनुसार स्पष्ट सफेद-स्पेस हैंडलिंग पसंद करता हूं)।

7

डिफ़ॉल्ट रूप से, XSLT टेम्पलेट्स <xsl:preserve-space> सेट है, जो आपके उत्पादन में खाली स्थान के रखेंगे । को व्हाइटस्पेस को हटाने के लिए कहने के लिए आप <xsl:strip-space elements="*"> जोड़ सकते हैं।

तुम भी तो की तरह एक सामान्य अंतरिक्ष निर्देश, शामिल करने के लिए आवश्यकता हो सकती है:

<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template> 

यहाँ एक example for preserve/strip space from W3 Schools है।

+9

डब्ल्यू 3 स्कूल! = डब्ल्यू 3 संदर्भ, डब्ल्यू 3 संदर्भ यहां है -> http://www.w3.org/TR/xslt#strip – Skuld

2

टैब को हटाने के अलावा, अलग लाइनों को बनाए रखने के बाद, मैंने निम्नलिखित XSLT 1.0 दृष्टिकोण को आजमाया, और यह बेहतर काम करता है। संस्करण 1.0 या 2.0 का आपका उपयोग काफी हद तक निर्भर करता है कि आप किस प्लेटफ़ॉर्म का उपयोग कर रहे हैं। ऐसा लगता है कि .NET तकनीक अभी भी एक्सएसएलटी 1.0 पर निर्भर है, और इसलिए आप अत्यधिक गन्दा टेम्पलेट तक सीमित हैं (नीचे देखें)। यदि आप जावा या कुछ और का उपयोग कर रहे हैं, तो कृपया बहुत नीचे की तरफ सूचीबद्ध क्लीनर एक्सएसएलटी 2.0 दृष्टिकोण देखें।

ये उदाहरण आपकी विशिष्ट आवश्यकताओं को पूरा करने के लिए आपके द्वारा विस्तारित किए जाने हैं। मैं यहां उदाहरण के रूप में टैब का उपयोग कर रहा हूं, लेकिन यह एक्स्टेंसिबल होने के लिए पर्याप्त सामान्य होना चाहिए।

एक्सएमएल:

<?xml version="1.0" encoding="UTF-8"?> 
<text> 
     adslfjksdaf 

       dsalkfjdsaflkj 

      lkasdfjlsdkfaj 
</text> 

... और XSLT 1.0 टेम्पलेट (आवश्यक अगर आप नेट का उपयोग करें):

:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template name="search-and-replace"> 
    <xsl:param name="input"/> 
    <xsl:param name="search-string"/> 
    <xsl:param name="replace-string"/> 
    <xsl:choose> 
    <xsl:when test="$search-string and 
        contains($input,$search-string)"> 
     <xsl:value-of 
      select="substring-before($input,$search-string)"/> 
     <xsl:value-of select="$replace-string"/> 
     <xsl:call-template name="search-and-replace"> 
     <xsl:with-param name="input" 
       select="substring-after($input,$search-string)"/> 
     <xsl:with-param name="search-string" 
       select="$search-string"/> 
     <xsl:with-param name="replace-string" 
       select="$replace-string"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$input"/> 
    </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template>     
    <xsl:template match="text"> 
    <xsl:call-template name="search-and-replace"> 
    <xsl:with-param name="input" select="text()" /> 
    <xsl:with-param name="search-string" select="'&#x9;'" /> 
    <xsl:with-param name="replace-string" select="''" /> 
    </xsl:call-template>  
    </xsl:template> 
</xsl:stylesheet> 

XSLT 2.0 replace समारोह के साथ इस तुच्छ बनाता है

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     exclude-result-prefixes="xs" 
     version="2.0"> 
<xsl:template match="text"> 
    <xsl:value-of select="replace(text(), '&#x9;', '')" /> 
</xsl:template> 
</xsl:stylesheet> 
1

अन्य ने पहले से ही सामान्य समस्या को इंगित कर दिया है। अपने स्टाइलशीट के लिए विशिष्ट एक है कि आप अल्पविराम के लिए <xsl:text> भूल गया है:

<xsl:choose> 
    <xsl:when test="@TYPE"> 
    <xsl:value-of select="@TYPE" />, 
    </xsl:when> 
    <xsl:otherwise>Home </xsl:otherwise> 
    </xsl:choose> 
    <xsl:value-of select="STREET" />, 
    <xsl:value-of select="CITY" />, 
    <xsl:value-of select="STATE" />, 
    <xsl:value-of select="ZIP" />, 

यह हर अल्पविराम महत्वपूर्ण निम्नलिखित खाली स्थान के लिए बनाता है, और इसलिए यह उत्पादन में समाप्त होता है। यदि आप प्रत्येक कॉमा को <xsl:text> में लपेटते हैं, तो समस्या गायब हो जाती है।

इसके अलावा, disable-output-escaping से छुटकारा पाएं। यह यहां कुछ भी नहीं करता है, क्योंकि आप एक्सएमएल आउटपुट नहीं कर रहे हैं।

1

अपने xslt में एक टेम्पलेट जोड़ें

<xsl:template match="text()"/> 
+0

क्यों? कैसे? आपका उत्तर धन्यवाद, लेकिन हमेशा अधिक जानकारी दें। – peterh

0

मेरे previouse जवाब गलत है, सभी के लिए अल्पविराम टैग 'पाठ'

<?xml version="1.0" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="/PHONEBOOK"> 
     <xsl:for-each select="LISTING"> 
      <xsl:value-of select="RELATION" /><xsl:text>, </xsl:text> 
      <xsl:value-of select="FIRST" /><xsl:text>, </xsl:text> 
      <xsl:value-of select="LAST" /><xsl:text>, </xsl:text> 

       <xsl:for-each select="ADDRESS"> 
        <xsl:choose> 
         <xsl:when test="@TYPE"> 
          <xsl:value-of select="@TYPE" /><xsl:text>,</xsl:text> 
         </xsl:when> 
         <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise> 
        </xsl:choose> 
       <xsl:value-of select="STREET/text()" /><xsl:text>,</xsl:text> 
        <xsl:value-of select="CITY/text()" /><xsl:text>,</xsl:text> 
        <xsl:value-of select="STATE/text()" /><xsl:text>,</xsl:text> 
        <xsl:value-of select="ZIP/text()" /><xsl:text>,</xsl:text> 
       </xsl:for-each> 

      <xsl:for-each select="PHONE"> 
       <xsl:choose> 
        <xsl:when test="@TYPE"> 
         <xsl:value-of select="@TYPE" /> 
        </xsl:when> 
        <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise> 
       </xsl:choose> 
       <xsl:value-of select="." /><xsl:text >, </xsl:text> 
      </xsl:for-each> 

      <xsl:if test="EMAIL"> 
       <xsl:for-each select="EMAIL"> 
        <xsl:choose> 
         <xsl:when test="@TYPE"> 
          <xsl:value-of select="@TYPE" /><xsl:text > </xsl:text> 
         </xsl:when> 
         <xsl:otherwise><xsl:text >Personal </xsl:text></xsl:otherwise> 
        </xsl:choose> 
        <xsl:value-of select="." /><xsl:text >, </xsl:text> 
       </xsl:for-each> 
      </xsl:if> 
      <xsl:text>&#10;&#13;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="text()|@*"> 
     <xsl:text>-</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 
0

कोड है जो हम कच्चे XML स्वरूप के लिए इस्तेमाल किया संशोधित के माध्यम से उत्पादन किया जाना चाहिए नीचे की रेखाओं को हटाकर फ़ाइल निर्यात किए गए एक्सेल में अतिरिक्त खाली सफेद रिक्त स्थान हटा दी जाएगी।

इंडेंटेड प्रॉपर्टी सिस्टम के साथ स्वरूपण करते समय उन अतिरिक्त रिक्त सफेद रिक्त स्थान जोड़ रहे हैं।

नीचे पंक्ति की तरह xml स्वरूपण से संबंधित टिप्पणी पंक्तियां और प्रयास करें।

xmlWriter.Formatting = System.Xml.Formatting.Indented; 
संबंधित मुद्दे