जांचें कि क्या कोई स्ट्रिंग XSLT में शून्य या रिक्त है


325

यदि XSL के साथ कोई मान शून्य या खाली है तो मैं कैसे जांच सकता हूं ?

उदाहरण के लिए, अगर categoryNameखाली है? मैं एक निर्माण का चयन करते समय उपयोग कर रहा हूँ ।

उदाहरण के लिए:

<xsl:choose>
    <xsl:when test="categoryName !=null">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

क्या आप कोड उदाहरण का विस्तार कर सकते हैं?
निक एलन

आपके उपयोग के मामले के आधार पर, आप शायद xsl:whenनोड-टेस्ट के लिए उपयोग नहीं करना चाहते हैं । <xsl:template match="Category[categoryName[not(node())]]">...एक साथ विचार करें <xsl:template match="Category">...। फिर प्रोसेसर आपके लिए सही निर्णय लेगा और आपको xsl:chooseअब नेस्टेड में व्यापार तर्क लिखने की आवश्यकता नहीं है। कई मामलों में, मेल खाने वाले टेम्प्लेट का उपयोग करने से स्टाइलशीट लिखना आसान हो जाता है।
हाबिल

जवाबों:


322
test="categoryName != ''"

संपादित करें : यह मेरे विचार में, "[नहीं] अशक्त या खाली" के रूप में सबसे अधिक संभावित व्याख्या को कवर करता है, क्योंकि यह प्रश्न से अनुमानित है, इसमें छद्म कोड और XSLT के साथ मेरा अपना प्रारंभिक अनुभव शामिल है। Ie, "निम्नलिखित जावा के बराबर क्या है?":

!(categoryName == null || categoryName.equals(""))

अधिक विवरणों के लिए, विशिष्ट रूप से रिक्त बनाम रिक्त की पहचान करने के लिए, नीचे जॉनहॉउस का उत्तर देखें और / या XSLT ' फिडेल ' मैंने उस उत्तर से अनुकूलित किया है, जिसमें माइकल के की टिप्पणी के साथ-साथ छठी संभावित व्याख्या का विकल्प भी शामिल है।


14
इस परीक्षण का विस्तृत शब्दार्थ है: कम से कम एक श्रेणीनाम तत्व जिसका स्ट्रिंग मान एक रिक्त स्ट्रिंग है, तो वापस लौटें।
jelovirt

14
@jelovirt के कहने का मतलब यह था कि अगर कम से कम एक श्रेणी नहीं है तो क्या वह खाली स्ट्रिंग नहीं है? (मैं एक xsl नौसिखिया हूँ, इसलिए अपने प्रश्न के लिए किसी भी संभावित मूर्खता को क्षमा कर सकता हूँ।)
joedevon

10
स्वीकृत और अत्यधिक मतदान के समय यह उत्तर भी बहुत भ्रामक है। यह वास्तव में निर्भर करता है कि आप "शून्य या रिक्त" से क्या मतलब है। यदि आप एक परीक्षण चाहते हैं जो सफल होता है यदि श्रेणीनाम या तो अनुपस्थित है, या शून्य-लंबाई मान के साथ मौजूद है, तो आपको उपयोग करना चाहिए test="not(categoryName = '')"। यदि श्रेणी नाम अनुपस्थित है, तो आपूर्ति किया गया उत्तर गलत हो जाएगा, जो प्रश्न की मेरी व्याख्या में यह गलत उत्तर है।
माइकल

2
@MichaelKay: मैंने अधिक विवरण प्रदान करने के लिए उत्तर अपडेट किया है। टिप्पणी के लिए और Saxon XSLT प्रोसेसर के लिए धन्यवाद!
स्टीमर

मैं कैसे अनुवाद कर सकता हूं <xsl:for-each select="root/*[matches(name(.), 'grp')]">ताकि इसका उपयोग VS2010 में किया जा सके?
Si8

276

किसी भी अन्य जानकारी के अभाव में, मैं निम्नलिखित XML मानूंगा:

<group>
    <item>
        <id>item 1</id>
        <CategoryName>blue</CategoryName>
    </item>
    <item>
        <id>item 2</id>
        <CategoryName></CategoryName>
    </item>
    <item>
        <id>item 3</id>
    </item>
    ...
</group>

एक नमूना उपयोग के मामले की तरह दिखेगा:

<xsl:for-each select="/group/item">
    <xsl:if test="CategoryName">
        <!-- will be instantiated for item #1 and item #2 -->
    </xsl:if>
    <xsl:if test="not(CategoryName)">
        <!-- will be instantiated for item #3 -->
    </xsl:if>
    <xsl:if test="CategoryName != ''">
        <!-- will be instantiated for item #1 -->
    </xsl:if>
    <xsl:if test="CategoryName = ''">
        <!-- will be instantiated for item #2 -->
    </xsl:if>
</xsl:for-each>

आप उदाहरणों के लिए परीक्षण कैसे करते हैं </CategoryName>? , खाली स्ट्रिंग परीक्षण इस के लिए काम नहीं करते हैं
रफ़ियन

3
यह सराहना की जाती है कि आपने प्रत्येक उदाहरण को दिखाने के लिए कई उदाहरणों को शामिल किया है।
डबल जे

1
@raffian: XSLT, या संबंधित तकनीकों (XQuery, DOM, XDM, स्कीमा आदि) में, अंत-टैग को अलग निकाय नहीं माना जाता है। इसके बजाय, आप केवल इस मामले में नोड्स या तत्वों से निपटते हैं, जो कि स्टार्ट-टैग और एंड-टैग के बीच संपूर्ण है। संक्षेप में, परीक्षण के लिए कोई रास्ता नहीं है </CategoryName>और न ही इसकी कोई आवश्यकता है।
हाबिल

4
मैंने विशेष रूप से इस उत्तर के लिए प्रश्न को तारांकित किया, और जबकि प्रश्न बहुत पुराना है, यह चयनित उत्तर होने के लिए अधिक योग्य लगता है
पैट्रिक

68

से खाली तत्व :

यह जांचने के लिए कि क्या एक निश्चित नोड का मान खाली है

यह इस बात पर निर्भर करता है कि आपके खाली होने का क्या मतलब है।

  • इसमें कोई बच्चा नहीं है: not(node())
  • कोई पाठ सामग्री नहीं है: not(string(.))
  • इसमें व्हॉट्सएप के अलावा कोई टेक्स्ट नहीं है: not(normalize-space(.))
  • इसमें टिप्पणियों के अलावा कुछ नहीं है: not(node()[not(self::comment())])

2
+1। कुछ नोट। पहला बुलेटपॉइंट पाठ-सामग्री के लिए भी परीक्षण करता है, जो एक नोड भी है। किसी भी गहराई पर किसी भी पाठ नोड के लिए दूसरा बुलेटपॉइंट परीक्षण, यदि आप जानना चाहते हैं कि क्या वर्तमान नोड में पाठ नहीं है, लेकिन अन्य नोड्स हो सकते हैं, तो आप उपयोग कर सकते हैं not(text())। आपकी दूसरी बुलेट का विकल्प भी है not(.//text())। जैसा कि आपकी आखिरी गोली से पता चलता है: "शून्यता" पर विचार करने के कई तरीके हैं;)।
हाबिल

बहुत ही व्यावहारिक: यदि एक स्ट्रिंग खाली नहीं है, तो आप केवल स्ट्रिंग का परीक्षण कर सकते हैं! if ($mystring) then ... else ...
फेलिक्स डॉम्बेक

22

व्हाट अबाउट?

test="not(normalize-space(categoryName)='')"

1
यह बहुत अच्छा काम करता है। यहां तक ​​कि जब कोई टिप्पणी अंदर होती है <categoryName> <!-- some comment --> </categoryName>और अन्यथा कोई सार्थक पाठ नहीं होता है, तब भी यह मूल्यांकन करता हैtrue
rustyx

9

पहला दो शून्य मूल्य के साथ और दूसरा दो सौदे खाली स्ट्रिंग के साथ।

<xsl:if test="USER/FIRSTNAME">
    USERNAME is not null
</xsl:if>
<xsl:if test="not(USER/FIRSTNAME)">
    USERNAME is null
 </xsl:if>
 <xsl:if test="USER/FIRSTNAME=''">
     USERNAME is empty string
 </xsl:if>
 <xsl:if test="USER/FIRSTNAME!=''">
     USERNAME is not empty string
 </xsl:if>

1
भयानक। यदि कई उपयोगकर्ता या कई प्रथम नाम हैं तो क्या होगा? xsl:apply-templatesआप जो चाहते हैं उसे प्राप्त करने के लिए टेम्प्लेट का उपयोग करें और मिलान करें , बहुत आसान।
हाबिल

7

कुछ मामलों में, आप जानना चाह सकते हैं कि मूल्य विशेष रूप से अशक्त है, जो XML का उपयोग करते समय विशेष रूप से आवश्यक है जो .NET ऑब्जेक्ट्स से क्रमबद्ध किया गया है। जबकि इसके लिए स्वीकृत उत्तर काम करता है, यह उसी परिणाम को भी लौटाता है जब स्ट्रिंग खाली या खाली होता है, अर्थात '', इसलिए आप अंतर नहीं कर सकते।

<group>
    <item>
        <id>item 1</id>
        <CategoryName xsi:nil="true" />
    </item>
</group>

तो आप बस विशेषता का परीक्षण कर सकते हैं।

<xsl:if test="CategoryName/@xsi:nil='true'">
   Hello World.
</xsl:if>

कभी-कभी सटीक स्थिति को जानना आवश्यक होता है और आप यह जांच नहीं कर सकते हैं कि क्या श्रेणी नाम त्वरित है, क्योंकि इसके विपरीत जावास्क्रिप्ट कहते हैं

<xsl:if test="CategoryName">
   Hello World.
</xsl:if>

एक अशक्त तत्व के लिए सही लौटेगा।


6

मुझे पता है कि यह प्रश्न पुराना है, लेकिन सभी उत्तरों के बीच, मुझे एक याद आती है जो कि XSLT विकास में इस उपयोग-मामले के लिए एक सामान्य दृष्टिकोण है।

मैं कल्पना कर रहा हूं कि ओपी से लापता कोड कुछ इस तरह दिखता है:

<xsl:template match="category">
    <xsl:choose>
        <xsl:when test="categoryName !=null">
            <xsl:value-of select="categoryName " />
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="other" />
        </xsl:otherwise>
    </xsl:choose>
</category>

और यह इनपुट कुछ इस तरह दिखता है:

<categories>
    <category>
       <categoryName>Books</categoryName>
    </category>
    <category>
       <categoryName>Magazines</categoryName>
       <categoryName>Periodicals</categoryName>
       <categoryName>Journals</categoryName>
    </category>
    <category>
        <categoryName><!-- please fill in category --></categoryName>
    </category>
    <category>
        <categoryName />
    </category>
    <category />
</categories>

यानी, मेरा मानना ​​है कि शून्य, खाली, एकल या कई categoryNameतत्व हो सकते हैं। इन सभी मामलों से निपटने के लिए xsl:choose-स्टाइल कंस्ट्रक्शंस का उपयोग करना , या दूसरे शब्दों में, अनिवार्य रूप से, जल्दी से गड़बड़ हो रहा है (और भी अधिक अगर तत्व विभिन्न स्तरों पर हो सकते हैं!)। XSLT में एक विशिष्ट प्रोग्रामिंग मुहावरा टेम्पलेट्स का उपयोग कर रहा है (इसलिए टी इन XSLT), जो कि घोषणात्मक प्रोग्रामिंग है, न कि अत्यावश्यक (आप प्रोसेसर को यह नहीं बताएं कि आपको क्या करना है, आप बस यह बताएं कि कुछ शर्तों को पूरा करने पर आप आउटपुट क्या चाहते हैं)। इस उपयोग-मामले के लिए, जो निम्नलिखित की तरह कुछ देख सकता है:

<!-- positive test, any category with a valid categoryName -->
<xsl:template match="category[categoryName[text()]]">
    <xsl:apply-templates />
</xsl:template>

<!-- any other category (without categoryName, "null", with comments etc) -->
<xsl:template match="category">
    <xsl:text>Category: Other</xsl:text>
</xsl:template>

<!-- matching the categoryName itself for easy handling of multiple names -->
<xsl:template match="categoryName">
    <xsl:text>Category: </xsl:text>
    <xsl:value-of select="." />
</xsl:template>

यह काम करता है (किसी भी XSLT संस्करण के साथ), क्योंकि ऊपर दिए गए पहले वाले में एक उच्च वरीयता है (इसमें एक विधेय है)। "फ़ॉल-थ्रू" मिलान टेम्पलेट, दूसरा वाला, कुछ भी पकड़ता है जो मान्य नहीं है। तीसरा तब आउटपुट का ख्याल रखता हैcategoryName उचित तरीके मूल्य ।

ध्यान दें कि इस परिदृश्य में विशिष्ट रूप से मिलान करने की आवश्यकता नहीं है categoriesया category, क्योंकि प्रोसेसर स्वचालित रूप से सभी बच्चों को संसाधित करेगा, जब तक कि हम इसे अन्यथा नहीं बताएं (इस उदाहरण में, दूसरा और तीसरा टेम्पलेट आगे बच्चों को संसाधित नहीं करते हैं, क्योंकि इसमें कोई भी नहीं xsl:apply-templatesहै) उन्हें)।

यह दृष्टिकोण अधिक आसानी से विस्तार योग्य है, फिर अनिवार्य दृष्टिकोण, क्योंकि यह स्वचालित रूप से कई श्रेणियों से संबंधित है और इसे अन्य तत्वों या अपवादों के लिए केवल एक अन्य मिलान टेम्पलेट जोड़कर विस्तारित किया जा सकता है। यदि शाखाओं के बिना प्रोग्रामिंग

नोट: nullXML जैसी कोई चीज नहीं है । इसमें xsi: nil है , लेकिन इसका उपयोग शायद ही कभी किया जाता है, खासकर किसी प्रकार के स्कीमा के बिना अनछुए परिदृश्यों में शायद ही कभी।


1
" अगर शाखाओं के बिना प्रोग्रामिंग " का उल्लेख करने पर बधाई । कुछ लोग हैं जो इस के महत्व को समझने में विफल रहते हैं। उन सभी के लिए यहाँ इस विषय पर एक बहुत ही बढ़िया Pluralsight कोर्स का लिंक दिया गया है : Zoran Horvat द्वारा " Tactical Design Patterns in .NET: Control Flow ": app.pluralsight.com/library/courses// ए-रीड!
दिमित्रे नोवत्चेव

5

यदि XSL के साथ कोई मान शून्य या खाली है तो मैं कैसे जांच सकता हूं?

उदाहरण के लिए, अगर categoryNameखाली है?

यह शायद सबसे सरल XPath अभिव्यक्ति है (स्वीकृत उत्तर में एक विपरीत के लिए एक परीक्षण प्रदान करता है, और लंबे समय तक होगा, अगर नकारात्मक हो):

not(string(categoryName))

स्पष्टीकरण :

not()उपरोक्त फ़ंक्शन का तर्क false()ठीक उसी समय है जब categoryNameसंदर्भ आइटम का कोई बच्चा ("अशक्त") नहीं है, या (एकल ऐसे) categoryNameबच्चे का स्ट्रिंग मान है - खाली स्ट्रिंग।

मैं एक निर्माण का चयन करते समय उपयोग कर रहा हूँ ।

उदाहरण के लिए:

<xsl:choose>
    <xsl:when test="categoryName !=null">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

XSLT 2.0 में उपयोग :

<xsl:copy-of select="concat(categoryName,  $vOther[not(string(current()/categoryName))])"/>

यहाँ एक पूर्ण उदाहरण है :

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vOther" select="'Other'"/>

 <xsl:template match="/">
  <xsl:copy-of select="concat(categoryName,$vOther[not(string(current()/categoryName))])"/>
 </xsl:template>
</xsl:stylesheet>

जब यह परिवर्तन निम्नलिखित XML दस्तावेज़ पर लागू होता है:

<categoryName>X</categoryName>

वांछित, सही परिणाम उत्पन्न होता है :

X

जब इस XML दस्तावेज़ पर लागू किया जाता है :

<categoryName></categoryName>

या इस पर:

<categoryName/>

या इस पर

<somethingElse>Y</somethingElse>

सही परिणाम उत्पन्न होता है :

Other

इसी तरह, इस XSLT 1.0 परिवर्तन का उपयोग करें :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vOther" select="'Other'"/>

  <xsl:template match="/">
    <xsl:copy-of select=
    "concat(categoryName,  substring($vOther, 1 div not(string(categoryName))))"/>
  </xsl:template>
</xsl:stylesheet>

ध्यान दें : कोई भी सशर्त का उपयोग नहीं किया जाता है। इस अच्छे Pluralsight पाठ्यक्रम में सशर्त निर्माण से बचने के महत्व के बारे में और जानें:

" .NET में टैक्टिकल डिज़ाइन पैटर्न: कंट्रोल फ़्लो "


हाय दिमित्रे, मुझे 1.0 के लिए आपके समाधान की आवश्यकता है, तो क्या मुझे इसे हर टैग में कोड करने की आवश्यकता है जो मेरे पास है या पूरे XML के लिए इसे लागू करने का एक सरल तरीका है?
zyberjock

@zyberjock, यह स्पष्ट नहीं है कि आप क्या पूछ रहे हैं। कृपया, एक प्रश्न पोस्ट करें और मुझे एक लिंक के साथ एक टिप्पणी भेजें। कैसे एक अच्छा सवाल पूछने के लिए दिशा निर्देशों का पालन करें।
दिमित्रे नोवाचेव

हाय @Dimitre, मैंने एक सवाल यहां पोस्ट किया stackoverflow.com/questions/38150093/…
zyberjock

4

यदि कोई संभावना है कि तत्व XML में मौजूद नहीं है, तो मैं दोनों का परीक्षण करूंगा कि तत्व मौजूद है और स्ट्रिंग-लंबाई शून्य से अधिक है:

<xsl:choose>
    <xsl:when test="categoryName and string-length(categoryName) &gt; 0">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

3
एक खाली नोड सेट का स्ट्रिंग मान (जो कि XPath अभिव्यक्ति categoryNameआपको देता है जब categoryNameवर्तमान संदर्भ में कोई बाल तत्व नहीं हैं ) को रिक्त स्ट्रिंग के रूप में परिभाषित किया गया है, इसलिए यह निरर्थक है - string-length(categoryName)कोई categoryNameतत्व नहीं होने पर शून्य है ।
इयान रॉबर्ट्स

3

यदि नोड में xpath की तरह इनपुट xml में कोई मान उपलब्ध नहीं है,

<node>
    <ErrorCode/>
</node>

स्ट्रिंग () फ़ंक्शन रिक्त मान में परिवर्तित होता है। तो यह ठीक काम करता है:

string(/Node/ErrorCode) =''

2

मेरे लिए कुछ इस तरह काम करता है:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) = 'NaN'"> - </xsl:when> 
  <xsl:otherwise> 
    <xsl:number value="categoryName" />
  </xsl:otherwise>
</xsl:choose>

या फिर इसके विपरीत:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) != 'NaN'">
    <xsl:number value="categoryName" />
  </xsl:when> 
  <xsl:otherwise> - </xsl:otherwise>
</xsl:choose>

नोट: यदि आप अशक्त मानों की जांच नहीं करते हैं या अशक्त मूल्यों को संभालते हैं, तो IE7 NaN के बजाय -2147483648 देता है।


1

मैं वास्तव में यह बेहतर पाया सिर्फ स्ट्रिंग की लंबाई के लिए परीक्षण क्योंकि कई बार क्षेत्र शून्य नहीं है, बस खाली है

<xsl: जब परीक्षण = "स्ट्रिंग-लंबाई (फ़ील्ड-यू-वॉन्ट-टू-टेस्ट) <1">


0

मेरे अनुभव से सबसे अच्छा तरीका है:

<xsl:when test="not(string(categoryName))">
    <xsl:value-of select="other" />
</xsl:when>
<otherwise>
    <xsl:value-of select="categoryName" />
</otherwise>

0

सरल श्रेणीनाम का उपयोग करें / पाठ () इस तरह के परीक्षण पर <categoryName/>और भी ठीक काम करता है <categoryName></categoryName>

<xsl:choose>
    <xsl:when test="categoryName/text()">
        <xsl:value-of select="categoryName" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.