使用XSLT打印xpath和元素和属性的值

时间:2014-08-27 07:22:10

标签: xslt

我想使用XSLT打印元素和属性的路径(如果有的话)。例如

XML : 

    <root>
       <node attr='abc' module='try'>       
          <subnode>Roshan</subnode>
          <subnode>Chetan</subnode>
          <subnode>Jennifer</subnode>
       </node>
    </root>

    Output : 
    /root##
    /root/node##
    /root/node/@attr##abc
    /root/node/@module##try
    /root/node/subnode[1]##Roshan
    /root/node/subnode[2]##Chetan
    /root/node/subnode[3]##Jennifer

我正在尝试下面的代码段,但只能打印元素的路径及其值

<xsl:template match="*">
    <xsl:for-each select="ancestor-or-self::*">
        <xsl:value-of select="concat('/',local-name())" />
        <xsl:if
            test="(preceding-sibling::*|following-sibling::*)[local-name()=local-name(current())]">
            <xsl:value-of
                select="concat('[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')" />
        </xsl:if>
        <!-- <xsl:call-template name="attrData"></xsl:call-template> -->
    </xsl:for-each>
    <xsl:text>##</xsl:text>     
    <xsl:apply-templates select="node()" /> 
</xsl:template>

我是XSLT的新手。请帮忙!!!!

1 个答案:

答案 0 :(得分:0)

我制作了以下XSLT并将[position]添加到输出中。如果需要,您可以删除它。

这给出了这个输出:

/root[1]
/root[1]/node[1]
/root[1]/node[1]/@attr[1]##abc
/root[1]/node[1]/@module[1]##try
/root[1]/node[1]/subnode[1]##Roshan
/root[1]/node[1]/subnode[2]##Chetan
/root[1]/node[1]/subnode[3]##Jennifer

使用这个XSLT。使用两个输出模板,您可以选择如何打印Xpath。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns=""  version="2.0">
    <xsl:output method="text" encoding="utf-8" />


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

    <xsl:template match="*">
        <xsl:call-template name="generateXPath">     
            <xsl:with-param name="previous" select="''"/>            
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="generateXPath">
        <xsl:param name="previous" as="xs:string"/>
        <xsl:variable name="this" select="." as="node()"/>
        <xsl:if test="not(empty(.))">
            <xsl:variable name="thisXPath" select="concat($previous, '/', name(.),'[', count(preceding-sibling::*[name() = name($this)])+1,']')"></xsl:variable>
            <xsl:apply-templates select="." mode="output">
                <xsl:with-param name="previous" select="$previous"/>
            </xsl:apply-templates>
            <xsl:text>&#10;</xsl:text>
            <xsl:for-each select="*|@*">    
                <xsl:call-template name="generateXPath">        
                    <xsl:with-param name="previous" select="$thisXPath"/>            
                </xsl:call-template>
            </xsl:for-each>  
        </xsl:if>        
    </xsl:template>  

    <xsl:template  match="*" mode="output">
        <xsl:param name="previous" as="xs:string"/>
        <xsl:variable name="this" select="." as="node()"/>
            <xsl:variable name="thisXPath">
                <xsl:value-of select="concat($previous, '/', name(.),'[', count(preceding-sibling::*[name() = name($this)])+1,']')"></xsl:value-of>
                <xsl:if test="not(*)">
                    <xsl:value-of select="concat('##',text())"></xsl:value-of>
                </xsl:if>
            </xsl:variable>
            <xsl:value-of select="$thisXPath" />    
    </xsl:template> 

    <xsl:template  match="@*" mode="output">
        <xsl:param name="previous" as="xs:string"/>
        <xsl:variable name="this" select="." as="node()"/>
        <xsl:variable name="thisXPath" select="concat($previous, '/@', name(.),'[', count(preceding-sibling::*[name() = name($this)])+1,']','##',.)"></xsl:variable>
        <xsl:value-of select="$thisXPath" />      
    </xsl:template>


</xsl:stylesheet>