दिलचस्प पोस्ट
JSON के लिए जावास्क्रिप्ट एसोसिएटिव सरणी "HttpContext.Current" संपत्ति और संबंधित चीजों का क्रॉस-थ्रेड उपयोग Mod_rewrite की छिपी हुई विशेषताओं कैसे करें: कंसोल ऐप (सी #) में तालिका बनाने का सबसे अच्छा तरीका नोडजेएस और एक्सप्रेस के साथ एन्जेलरजेएस एचटीआर 5 मेोड का उपयोग करना मैं जावा में किसी की उम्र की गणना कैसे करूं? आईओएस 9 की नई सुविधा निशुल्क प्रोविजनिंग (ऐप्पल डेवलपर सदस्यता के बिना, केवल आपकी ऐप्पल आईडी के साथ, डिवाइस पर अपना ऐप चलाएं) जावा मुख्य विधि स्थिर क्यों है? पीडीओ बाँध पाराम बनाम स्विफ्ट में एक समयबद्ध ईवेंट को रद्द करें? आर – dplyr – mutate – गतिशील चर नामों का उपयोग करें PostgreSQL अलग आदेश के साथ पर अलग जीआईटी सबड्यूल और सबट्री के बीच मतभेद Android प्रक्रिया हत्यारा रूबी में "प्रत्येक" बनाम "के लिए"

एट्रिब्यूट्स पर XSLT 3-स्तरीय ग्रुपिंग

ठीक है, मुझे पता है कि इस पर भिन्नताएं पूछे गए हैं और उत्तर दिए गए हैं; मैं उन्हें पूरे दिन पढ़ रहा था, लेकिन मैं अभी भी फंस गया हूँ। तो, यहां जाता है:

मुझे कुछ XML से HTML में एक सारांश सूची बनाने की आवश्यकता है

इस XML को देखते हुए:

<Root><!-- yes, I know I don't need a 'Root' element! Legacy code... --> <Plans> <Plan AreaID="1" UnitID="83"> <Part ID="9122" Name="foo" /> <Part ID="9126" Name="bar" /> </Plan> <Plan AreaID="1" UnitID="86"> <Part ID="8650" Name="baz" /> </Plan> <Plan AreaID="2" UnitID="26"> <Part ID="215" Name="quux" /> </Plan> <Plan AreaID="1" UnitID="95"> <Part ID="7350" Name="meh" /> </Plan> </Plans> </Root> 

मुझे उत्सर्जन की आवश्यकता है:

 <ol> <li>Area 1: <ol><!-- units in Area 1 --> <li>Unit 83: <ol> <li>Part 9122 (foo)</li> <li>Part 9126 (bar)</li> </ol> </li> <li>Unit 86: <ol> <li>Part 8650 (baz)</li> </ol> <li>Unit 95: <ol> <li>Part 7350 (meh)</li> </ol> </li> </ol><!-- /units in Area 1--> </li> <li>Area 2: <ol><!-- units in Area 2 --> <li>Unit 26: <ol> <li>Part 215 (quux)</li> </ol> </li> </ol><!-- /units in Area 2--> </li> </ol> 

मेरे बाहरी समूह काम कर रहे हैं – मैं क्षेत्र 1 और 2 के लिए शीर्ष स्तर की सूची तत्व प्राप्त करता हूं। लेकिन मैं क्षेत्रों में इकाइयों के अनुक्रमों को नहीं प्राप्त कर सकता – मुझे या तो कोई आउटपुट नहीं मिल रहा है, या एक ही मूल्य दोहरा रहा है। मैं भी भाग के स्तर तक नहीं मिला है 🙁

मैं इस तरह एक स्टाइलशीट पर काम कर रहा हूं:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" <xsl:output method="html" indent="yes"/> <xsl:key name="kAreaID" match="Plan" use="@AreaID" /> <xsl:key name="kUnitID" match="Plan" use="@UnitID" /> <xsl:template match="/Root/Plans"> <html><head><title>test grouping</title></head> <body> <ol> <xsl:for-each select="./Plan[generate-id(.) = generate-id( key( 'kAreaID', @AreaID )[1] )]" > <xsl:sort order="ascending" select="./@AreaID" /> <li>Area <xsl:value-of select="@AreaID"/>: <ol> <xsl:for-each select="key( 'kUnitID', @UnitID )"> <li>Unit <xsl:value-of select="@UnitID"/>: <ol> <li>(Parts go here...)</li> </ol> </li> </xsl:for-each> </ol> </li> </xsl:for-each> </ol> </body> </html> </xsl:template> </xsl:stylesheet> 

कोई भी मदद बहुत ही सराहनीय होगी!

वेब के समाधान से एकत्रित समाधान "एट्रिब्यूट्स पर XSLT 3-स्तरीय ग्रुपिंग"

यहाँ Muenchian समूह समाधान है जो आप के लिए देख रहे हैं।

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

यहाँ मेरा संशोधित XSLT 1.0 समाधान है। यह मूल समाधान की तुलना में अधिक जटिल नहीं है:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:key name="kPlanByArea" match="Plan" use="@AreaID" /> <xsl:key name="kPlanByAreaAndUnit" match="Plan" use="concat(@AreaID, ',', @UnitID)" /> <xsl:template match="/"> <xsl:apply-templates select="Root/Plans" /> </xsl:template> <!-- main template --> <xsl:template match="Plans"> <ol> <!-- group by '{@AreaID}' (note the template mode!) --> <xsl:apply-templates mode="area-group" select=" Plan[ generate-id() = generate-id( key('kPlanByArea', @AreaID)[1] ) ] "> <xsl:sort select="@AreaID" data-type="number" /> </xsl:apply-templates> </ol> </xsl:template> <!-- template to output each '{@AreaID}' group --> <xsl:template match="Plan" mode="area-group"> <li> <xsl:value-of select="concat('Area ', @AreaID)" /> <ol> <!-- group by '{@AreaID},{@UnitID}' --> <xsl:apply-templates mode="unit-group" select=" key('kPlanByArea', @AreaID)[ generate-id() = generate-id( key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))[1] ) ] "> <xsl:sort select="@UnitID" data-type="number" /> </xsl:apply-templates> </ol> </li> </xsl:template> <!-- template to output each '{@AreaID},{@UnitID}' group --> <xsl:template match="Plan" mode="unit-group"> <li> <xsl:value-of select="concat('Unit ', @UnitID)" /> <ol> <xsl:apply-templates select=" key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))/Part "> <xsl:sort select="@UnitID" data-type="number" /> </xsl:apply-templates> </ol> </li> </xsl:template> <!-- template to output Parts into a list --> <xsl:template match="Part"> <li> <xsl:value-of select="concat('Part ', @ID, ' (', @Name ,')')" /> </li> </xsl:template> </xsl:stylesheet> 

चूंकि आपके एक्सएमएल को यह याद नहीं है, मैंने यूनिटआईडी को समूह पर जोड़ा है:

 <Plan AreaID="1" UnitID="86"> <Part ID="8651" Name="zzz" /> </Plan> 

और यहां आउटपुट है:

 <ol> <li>Area 1 <ol> <li>Unit 83 <ol> <li>Part 9122 (foo)</li> <li>Part 9126 (bar)</li> </ol> </li> <li>Unit 86 <ol> <li>Part 8650 (baz)</li> <li>Part 8651 (zzz)</li> </ol> </li> <li>Unit 95 <ol> <li>Part 7350 (meh)</li> </ol> </li> </ol> </li> <li>Area 2 <ol> <li>Unit 26 <ol> <li>Part 215 (quux)</li> </ol> </li> </ol> </li> </ol> 

चूंकि आपको एक्सएसएल कुंजी के साथ कठिन समय लगता है, यहां एक स्पष्टीकरण का मेरा प्रयास है:

एक <xsl:key> सरणी के बराबर है (मैप, हैश, आप इसे जो भी कहते हैं) कई प्रोग्रामिंग भाषाओं में जाना जाता है इस:

 <xsl:key name="kPlanByAreaAndUnit" match="Plan" use="concat(@AreaID, ',', @UnitID)" /> 

एक डेटा संरचना उत्पन्न करता है जिसे इस तरह जावास्क्रिप्ट में व्यक्त किया जा सकता है:

 var kPlanByAreaAndUnit = { "1,83": ['array of all <Plan> nodes with @AreaID="1" and @UnitID="83"'], "1,86": ['array of all <Plan> nodes with @AreaID="1" and @UnitID="86"'], /* ... */ "1,95": ['array of all <Plan> nodes with @AreaID="1" and @UnitID="95"'] }; 

डेटा संरचना तक पहुंचने के लिए कार्य key() कहा जाता है इसलिए, यह XPath अभिव्यक्ति:

 key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID)) 

तार्किक बराबर है (जावास्क्रिप्ट में, दोबारा):

 kPlanByAreaAndUnit[this.AreaID + ',' + this.UnitID]; 

दिए गए कुंजी स्ट्रिंग (कुंजी हमेशा एक स्ट्रिंग होती है) से मेल खाने वाले सभी नोड्स के सरणी (एक नोड-सेट, अधिक सही) लौट रहा है। यह नोड-सेट एक्सएसएलटी में किसी अन्य नोड-सेट की तरह इस्तेमाल किया जा सकता है, जैसे कि आप "पारंपरिक" XPath के माध्यम से पुनर्प्राप्त करते हैं। इसका अर्थ है कि आप इसे शर्तों (भविष्यवाणी) लागू कर सकते हैं:

 <!-- first node only... --> key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))[1] <!-- nodes that have <Part> children only... --> key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))[Part] 

या इसे XPath नेविगेशन के लिए आधार के रूप में प्रयोग करें:

 <!-- the actual <Part> children of matched nodes... --> key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))/Part 

और इसी तरह। इसका यह भी अर्थ है कि हम इसे <xsl:apply-templates> लिए "चयन" अभिव्यक्ति के रूप में उपयोग कर सकते हैं, और हम इसे समूह के आधार के रूप में उपयोग कर सकते हैं। जो हमें ऊपर की स्टाइलशीट (यदि आप इस एक के चारों ओर अपना सिर लपेट कर लेते हैं) की ओर ले जाता है, तो आप बाकी के समाधान को भी समझ गए हैं):

 key('kPlanByArea', @AreaID)[ generate-id() = generate-id( key('kPlanByAreaAndUnit', concat(@AreaID, ',', @UnitID))[1] ) ] 

दोबारा जावास्क्रिप्ट में, इस रूप में व्यक्त किया जा सकता है:

 // the result will be a node-set, so we prepare an array var selectedNodes = []; // "key('kPlanByArea', @AreaID)" var nodeSet = kPlanByArea[this.AreaID]; // "[...]" - the [] actually triggers a loop that applies // the predicate expression to all nodes in the set, so we do: for (var i = 0; i < nodeSet.length; i++) { // use the current node for any calculations var c = nodeSet[i]; if ( // if the current node === the *first* node in kPlanByAreaAndUnit... generateId(c) == generateId(kPlanByAreaAndUnit[c.AreaID + ',' + c.UnitID][0]) ) { // ...include it in the resulting selection selectedNodes.push(c) } } 

अभिव्यक्ति के बाद, केवल उन नोड्स चुने गए हैं जो दिए गए "एरियाआईडी, यूनिटआईडी" संयोजन के साथ संबंधित पहले वाले हैं – प्रभावी रूप से हमने उन्हें "एरियाड, यूनिटआईडी" संयोजन पर समूहित किया है।

इस नोड-सेट पर एक टेम्पलेट को लागू करने के कारण हर संयोजन केवल एक बार प्रकट होता है। मेरा <xsl:template match="Plan" mode="unit-group"> फिर प्रत्येक समूह के लिए पूर्ण आउटपुट प्राप्त करने के लिए फिर से पूर्ण सूची पुनर्प्राप्त करता है।

मुझे उम्मीद है कि इस अवधारणा को समझाने के लिए जावास्क्रिप्ट का प्रयोग एक उपयोगी विचार था।

मुझे नहीं लगता कि आपको kUnitID कुंजी का उपयोग बिल्कुल भी करना चाहिए। इसके बजाय निम्नलिखित पंक्ति की जगह …

 <xsl:for-each select="key( 'kUnitID', @UnitID )"> 

..इस लाइन के बजाय, जो मौजूदा एरिया आईडी से मेल खाते के सभी हिस्सों पर लूप चाहिए

 <xsl:for-each select="key( 'kAreaID', @AreaID )"> 

और इस पाश के भीतर, आपके (पार्ट्स यहाँ जाएं …) कोड के लिए, आप फिर भागों के ऊपर लूप कर सकते हैं

 <xsl:for-each select="Part"> <li>Part (<xsl:value-of select="@ID" />)</li> </xsl:for-each> 

खैर, मैंने कुछ समय के लिए कुंजियों और Muenchian समूहों पर छोड़ दिया। मैं इसे मुश्किल से समझता हूं, और इसे दूर करने पर वांछित परिणाम नहीं मिला। मैं पुनरावर्तन, यद्यपि समझता हूं, और इसलिए मैं इस पुनरावर्ती दृष्टिकोण के साथ गया जो वांछित आउटपुट उत्पन्न करता है मुझे इसे http://www.biglist.com/lists/xsl-list/archives/200412/msg00865.html पर मिला

चर्चा धागा चेतावनी देता है कि प्रदर्शन बड़े इनपुट बनाम Muenchian दृष्टिकोण, और नीचे समाधान verbose और दोहराव है (मैं इसे छोटे और मुश्किल समझने के लिए इसे refactor सकता है ;-), लेकिन 1) यह वास्तव में मेरे लिए काम करता है, और 2) मेरी वर्तमान समस्या के लिए इनपुट सेट बहुत छोटा है, एक दर्जन से अधिक या तो नीचे-स्तरीय भाग नोड्स।

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- recursive grouping http://www.biglist.com/lists/xsl-list/archives/200412/msg00865.html --> <xsl:template match="//Plans"> <html> <head> <title>test grouping</title> </head> <body> <ol> <xsl:call-template name="PlanGrouping"> <xsl:with-param name="list" select="Plan"/> </xsl:call-template> </ol> </body> </html> </xsl:template> <xsl:template name="PlanGrouping"> <xsl:param name="list"/> <!-- Selecting the first Area ID as group identifier and the group itself--> <xsl:variable name="group-identifier" select="$list[1]/@AreaID"/> <xsl:variable name="group" select="$list[@AreaID = $group-identifier]"/> <!-- Do some work for the group --> <li> Area <xsl:value-of select="$group-identifier"/>: <ol> <xsl:call-template name="AreaGrouping"> <xsl:with-param name="list" select="$list[(@AreaID = $group-identifier)]"/> </xsl:call-template> </ol> </li> <!-- If there are other groups left, calls itself --> <xsl:if test="count($list)>count($group)"> <xsl:call-template name="PlanGrouping"> <xsl:with-param name="list" select="$list[not(@AreaID = $group-identifier)]"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="AreaGrouping"> <xsl:param name="list"/> <!-- Selecting the first Unit ID as group identifier and the group itself--> <xsl:variable name="group-identifier" select="$list[1]/@UnitID"/> <xsl:variable name="group" select="$list[@UnitID = $group-identifier]"/> <!-- Do some work for the group --> <li> Unit <xsl:value-of select="$group-identifier"/>: <ol> <xsl:call-template name="Parts"> <xsl:with-param name="list" select="$list[(@UnitID = $group-identifier)]"/> </xsl:call-template> </ol> </li> <!-- If there are other groups left, calls itself --> <xsl:if test="count($list)>count($group)"> <xsl:call-template name="AreaGrouping"> <xsl:with-param name="list" select="$list[not(@UnitID = $group-identifier)]"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="Parts"> <xsl:param name="list"/> <xsl:for-each select="$list/Part"> <li> Part <xsl:value-of select="@ID"/> (<xsl:value-of select="@Name"/>) </li> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

यह वही करता है जो आप चाहते हैं, लेकिन पुनरावर्ती के साथ, समूह नहीं। माफ करना, मैं अब भी सीख रहा हूं कि समूहिंग का भी उपयोग कैसे करें:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:key name="kAreaID" match="Plan" use="@AreaID" /> <xsl:key name="kUnitID" match="Plan" use="@UnitID" /> <xsl:template match="/Root/Plans"> <html> <head> <title>test grouping</title> </head> <body> <ol> <xsl:for-each select="./Plan[generate-id(.) = generate-id( key( 'kAreaID', @AreaID )[1] )]" > <xsl:sort order="ascending" select="./@AreaID" /> <xsl:variable name="curArea" select="@AreaID"/> <li> Area <xsl:value-of select="$curArea"/>: <ol> <xsl:for-each select="ancestor::Root/Plans/Plan[@AreaID = $curArea]"> <xsl:variable name="curUnit" select="@UnitID"/> <li> Unit <xsl:value-of select="$curUnit"/>: <ol> <xsl:for-each select="ancestor::Root/Plans/Plan[@AreaID = $curArea and @UnitID = $curUnit]/Part"> <li> Part <xsl:value-of select="concat(@ID, ' (', @Name, ')')"/> </li> </xsl:for-each> </ol> </li> </xsl:for-each> </ol> </li> </xsl:for-each> </ol> </body> </html> </xsl:template> </xsl:stylesheet>