2008-10-22 13 views
13

मुझे this page मुएनचियन विधि का वर्णन करता है, लेकिन मुझे लगता है कि मैं इसे गलत लागू कर रहा हूं।अद्वितीय नोड्स का चयन कैसे करें

पर विचार करें कि इस उम्र के एक सेट में वापसी करेंगे:

/doc/class/person/descriptive[(@name='age')]/value 

1..2..2..2..3..3..4..7

लेकिन मुझे प्रत्येक उम्र के लिए नोडसेट केवल एक नोड चाहिए।

1..2..3..4..7

इनमें से प्रत्येक, सभी मान लौटने के लिए लग रहे हैं अद्वितीय मान के स्थान:

/doc/class/person/descriptive[(@name='age')][not(value=preceding-sibling::value)]/value 
/doc/class/person/descriptive[(@name='age')]/value[not(value=preceding-sibling::value)] 

क्या बजे में याद कर रहा हूँ?

+0

ओह, ऐसा उदाहरण की तरह दिखता है मैं बाद में * मुएनचियन विधि नहीं थी - इसके बजाय लेखक इसके विपरीत क्या कर रहा था। – pc1oad1etter

उत्तर

20

यहाँ एक उदाहरण है

संपादित करें: चूंकि मूसियो ने टिप्पणी की है कि यह सूची में अंतिम आइटम को कैप्चर नहीं करता है, अगर यह एकमात्र समय लगता है।

/root/item[not(.=preceding-sibling::item)] 
+0

जाहिर है, आप अपनी वास्तविक फ़ाइल में प्रकार विशेषता या अन्य डेटा के आधार पर प्रतिबंधित करने के लिए अतिरिक्त XPath का उपयोग कर सकते हैं। मैं बस अपने त्वरित परीक्षण के दौरान वहां था। –

+0

यह भी ध्यान रखें कि XPath में "आइटम" कोई कीवर्ड नहीं है, यह XML दस्तावेज़ में तत्व का नाम है जो पिछले :: और पिछले-सिब्बल :: अक्ष काम कर रहे हैं। –

+1

मुझे नहीं लगता कि // // का उपयोग यहां दिया गया है, संरचना को दिया गया है, इसलिए हम सभी आइटम नोड्स जानते हैं, और केवल आइटम नोड्स रूट रूट नोड के नीचे दिखाई देते हैं, यह बेहतर है: रूट/आइटम [। ! = preceding-sibling] – markmnl

1

क्या आप पिछले मूल्य के बाद 'वर्णनात्मक' के संदर्भ में अनुपलब्ध नहीं हैं? निम्नलिखित की तरह कुछ बात:

<root> 
    <item type='test'>A</item> 
    <item type='test'>B</item> 
    <item type='test'>C</item> 
    <item type='test'>A</item> 
    <item type='other'>A</item> 
    <item type='test'>B</item> 
    <item type='other'>D</item> 
    <item type=''>A</item> 
</root> 

और XPath:

//preceding::item/preceding::item[not(.=preceding-sibling::item)]/text() 

परिणाम: एबीसीडी

/doc/class/person/descriptive[(@name='age')][not(value=preceding-sibling::descriptive[@name='age']/value)]/value 

(यह परीक्षण नहीं किया है)

14

यहाँ Muenchian BQ के जवाब के बारे में उनकी डेटा का उपयोग कर संस्करण है: कि और खाते में Fëanor की टिप्पणी लेते हुए यहां एक बेहतर समाधान है यह बदलने

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

    <xsl:output indent="yes" method="text"/> 
    <xsl:key name="item-by-value" match="item" use="."/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="/root/item"/> 
    </xsl:template> 

    <xsl:template match="item"> 
    <xsl:if test="generate-id() = generate-id(key('item-by-value', normalize-space(.)))"> 
     <xsl:value-of select="."/> 
     <xsl:text> 
</xsl:text> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="text()"> 
    <xsl:apply-templates/> 
    </xsl:template> 
</xsl:stylesheet> 

एक
बी देता है
सी
डी

  1. key()item के लिए टेम्पलेट में उपरोक्त लुकअप एक नोडसेट देता है जिसमें संदर्भ 0 नोड के समान स्ट्रिंग मान वाले सभी item तत्व होते हैं।
  2. यदि आप एक ऐसा फ़ंक्शन लागू करते हैं जो एक नोड को नोडसेट में अपेक्षा करता है, तो वह उस नोडसेट में पहले नोड पर काम करेगा।
  3. generate-id() पर सभी कॉल किसी दस्तावेज़ के माध्यम से एक ही पास के दौरान दिए गए नोड के लिए एक ही आईडी उत्पन्न करने की गारंटी दी जाती हैं।
  4. इसलिए, परीक्षण सही होगा यदि संदर्भ नोड key() कॉल द्वारा लौटाए गए पहले के समान नोड है।
+0

मैच के थोड़ा tweaking के साथ और पैरामीटर का उपयोग करें यह प्रत्येक तत्व के लिए एक आकर्षण की तरह काम किया; धन्यवाद! –

+0

@ChuckB यदि किसी आइटम तत्व में कोई मान होता है जिसमें दो रिक्त स्थान होते हैं तो इसे नहीं उठाया जाता है (उदाहरण के लिए ए बी)। कोई विचार यह क्यों है? –

+0

इस स्थिति में 'स्थिति()' कैसे काम करता है? मान लें कि आपने 'ए, ए, ए, बी, बी, बी' के नोडसेट के साथ शुरुआत की और इसे 'ए, बी' तक पहुंचा दिया, क्या 'ए' की नई स्थिति() 'प्राप्त करने का कोई तरीका होगा और 'बी', जो 'बी' के लिए' ए' और '2' के लिए' 1' होना चाहिए? – NessDan

2

मुएनचियन विधि नोड सेट से वस्तुओं की एक अनूठी सूची बनाने के लिए कुंजी का उपयोग करती है। अपने डेटा के लिए, कुंजी इस प्रकार दिखाई देगा:

<!-- Set the name to whatever you want --> 
<xsl:key name="PeopleAges" match="/doc/class/person/descriptive[@name = 'age']/value" use="." /> 

वहाँ से, मैं व्यक्तिगत रूप से xsl:apply-templates का प्रयोग करेंगे, लेकिन आप अन्य स्थानों में निम्नलिखित select विशेषता का उपयोग कर सकते हैं:

<!-- you can change `apply-templates` to: `copy-of` or `for-each`. --> 
<xsl:apply-templates select="/doc/class/person/descriptive[@name = 'age']/value[count(. | key('PeopleAges', .)[1]) = 1]" /> 

के लिए साथ मैच ऊपर बहुत सरल है:

<xsl:template match="person/descriptive[@name = 'age']/value"> 
    <strong>Age: </strong><xsl:value-of select="." /> 
</xsl:template> 
3

जो लोग अभी भी XSLT में कुछ चुने हुए अलग देखने के लिए:

XSLT 2.0, के साथ आप "अलग-मूल्यों (/ doc/वर्ग/व्यक्ति/वर्णनात्मक [(@ name = 'युग')]/मूल्य)" का उपयोग कर सकते

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