मेरे पास एक एक्सएमएल है जैसे:

<ast>
    <group>
        <Set>
            <location line="1" column="22" offset="22"/>
            <group>
                <Id value="foo">
                    <location line="1" column="31" offset="31"/>
                </Id>
            </group>
            <group>
                <Function>
                    <location line="1" column="22" offset="22"/>
                    <end-location line="1" column="49" offset="49"/>
                    <group>
                        <Id value="a">
                            <location line="1" column="35" offset="35"/>
                        </Id>
                        <Id value="b">
                            <location line="1" column="37" offset="37"/>
                        </Id>
                    </group>
                    <group>
                        <Return>
                            <location line="1" column="40" offset="40"/>
                            <Number value="0">
                                <location line="1" column="47" offset="47"/>
                            </Number>
                        </Return>
                    </group>
                </Function>
            </group>
        </Set>
        ...
    </group>
</ast>

जिसे मैं इस टेम्पलेट के साथ संसाधित करता हूं:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="text()" /><!-- remove blanks -->

    <xsl:template match="Set[group[position()=1]/Id][group[position()=2]/Function]">
        <function-def>
            <xsl:attribute name="name">
                <xsl:value-of select="group[position()=1]/Id/@value" />
                <xsl:text>(</xsl:text>
                <xsl:apply-templates select="group[position()=2]/Function" />
                <xsl:text>)</xsl:text>
            </xsl:attribute>
            <xsl:copy-of select="group/Function/location" />
            <xsl:copy-of select="group/Function/end-location" />
        </function-def>
    </xsl:template>

    <xsl:template match="Function/group[position()=1]/Id">
        <xsl:value-of select="@value" />
        <xsl:if test="position() != last()"><xsl:text>,</xsl:text></xsl:if>
    </xsl:template>

</xsl:stylesheet>

हालांकि अंतिम टेम्पलेट पर स्थिति position() != last() काम नहीं कर रही है। क्यों?

आउटपुट इस प्रकार प्रस्तुत करता है:

<?xml version="1.0"?>
<function-def name="foo(a,b,)">...

जबकि यह होना चाहिए:

<?xml version="1.0"?>
<function-def name="foo(a,b)">...
0
fferri 24 मई 2018, 19:49

1 उत्तर

सबसे बढ़िया उत्तर

यह काम कर रहा है, लेकिन उस तरीके से नहीं जैसा आप सोचते हैं....

आपके पहले टेम्पलेट में, आपके पास यह xsl:apply-templates है

<xsl:apply-templates select="group[position()=2]/Function" />

लेकिन आपके पास Function से मेल खाने वाला कोई टेम्प्लेट नहीं है, और इसलिए XSLT का बिल्ट-इन टेम्प्लेट नियम शुरू होते हैं, जो कि यह है...

<xsl:template match="*|/">
   <xsl:apply-templates/>
</xsl:template>

यह Group तत्वों का चयन करेगा, जिसके लिए फिर से कोई टेम्पलेट नहीं है। अब, जब यह <xsl:apply-templates/> करता है तो यह सभी चाइल्ड नोड्स का चयन करेगा, जिसमें XML को इंडेंट करने के लिए उपयोग किए गए खाली टेक्स्ट नोड्स शामिल हैं।

समस्या यह है कि जब आप position() = last() का परीक्षण कर रहे हैं तो आप चयनित सभी चाइल्ड नोड्स के सेट में तत्व की स्थिति का परीक्षण कर रहे हैं, जिसमें टेक्स्ट नोड्स शामिल हैं। अंतिम id के बाद एक खाली टेक्स्ट नोड है, इसलिए id अंतिम id तत्व हो सकता है, लेकिन यह अंतिम चाइल्ड नोड नहीं है।

एक समाधान, एक्सएसएलटी को खाली टेक्स्ट नोड्स को अलग करने के लिए कहना है, ताकि id फिर अंतिम चाइल्ड नोड बन जाए

 <xsl:strip-space elements="*" />

वैकल्पिक रूप से, आप group से मेल खाने वाला टेम्प्लेट जोड़ सकते हैं, और स्पष्ट रूप से केवल id नोड्स का चयन कर सकते हैं

<xsl:template match="Function/group[position()=1]">
    <xsl:apply-templates select="Id" />
</xsl:template>
2
Tim C 24 मई 2018, 20:08