在XSLT中选择并附加当前节点的文本值?

时间:2012-07-19 14:58:08

标签: xml xslt xpath xquery xslt-2.0

  

可能重复:
  Generate/get xpath from XML node java

这是previous question我提出的一个后续问题,(我决定再问一个问题,因为之前的问题似乎太大了。)

我有以下XSLT,它允许我将指定的XML String转换为一组XPath表达式:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="text()"/>

    <xsl:template match="*[not(*)]">
        <xsl:for-each select="ancestor-or-self::*">
            <xsl:value-of select="concat('/',local-name(),'[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates select="node()"/>
    </xsl:template>

</xsl:stylesheet>

例如,XML String:

<ns1:create xmlns:ns1='http://predic8.com/wsdl/material/ArticleService/1/'>
    <article xmlns:ns1='http://predic8.com/material/1/'>
        <name />
        <description />
        <price xmlns:ns1='http://predic8.com/common/1/'>
            <amount />
            <currency xmlns:ns1='http://predic8.com/common/1/‘>AUD</currency>
        </price>
        <id xmlns:ns1='http://predic8.com/material/1/‘>1</id>
    </article>
    <article xmlns:ns1='http://predic8.com/material/2/'>
        <name xmlns:ns1='http://predic8.com/material/2/'>some name</name>
        <description xmlns:ns1='http://predic8.com/material/2/'>some description</description>
        <price xmlns:ns1='http://predic8.com/common/2/'>
            <amount xmlns:ns1='http://predic8.com/common/2/'>00.01</amount>
            <currency xmlns:ns1='http://predic8.com/common/2/'>USD</currency>
        </price>
        <id xmlns:ns1='http://predic8.com/material/2/'>2</id>
    </article>
</ns1:create>

会变成:

/create[1]/article[1]/name[1]
/create[1]/article[1]/description[1]
/create[1]/article[1]/price[1]/amount[1]
/create[1]/article[1]/price[1]/currency[1] , AUD
/create[1]/article[1]/id[1] , 1
/create[1]/article[2]/name[1]
/create[1]/article[2]/description[1]
/create[1]/article[2]/price[1]/amount[1]
/create[1]/article[2]/price[1]/currency[1]
/create[1]/article[2]/id[1]

我的问题: 如何,我可以修改XSLT,以便我也可以选择并附加当前节点的文本值。另请注意,正如我在提供的示例XML文件中所说明的,某些节点可能不包含文本值等。

因此,对于上面的示例,我会期待类似的事情(例如逗号分隔输出):

/create[1]/article[1]/name[1] , 
/create[1]/article[1]/description[1] , 
/create[1]/article[1]/price[1]/amount[1] , 
/create[1]/article[1]/price[1]/currency[1] , 
/create[1]/article[1]/id[1] , 
/create[1]/article[2]/name[1] , some name
/create[1]/article[2]/description[1] , some description
/create[1]/article[2]/price[1]/amount[1] , 00.01
/create[1]/article[2]/price[1]/currency[1] , USD
/create[1]/article[2]/id[1] , 2

1 个答案:

答案 0 :(得分:0)

它应该像在适当的节点添加select=./text()一样简单,还是在我的问题中遗漏了一些微妙的内容?

<xsl:template match="*[not(*)]">
    <xsl:for-each select="ancestor-or-self::*">
        <xsl:value-of select="concat('/',local-name(),'[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
    </xsl:for-each>
    <xsl:text> , </xsl:text>
    <xsl:value-of select="./text()"/>
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates select="node()"/>
</xsl:template>

输出:

/create[1]/article[1]/name[1] , 
/create[1]/article[1]/description[1] , 
/create[1]/article[1]/price[1]/amount[1] , 
/create[1]/article[1]/price[1]/currency[1] , AUD
/create[1]/article[1]/id[1] , 1
/create[1]/article[2]/name[1] , some name
/create[1]/article[2]/description[1] , some description
/create[1]/article[2]/price[1]/amount[1] , 00.01
/create[1]/article[2]/price[1]/currency[1] , USD
/create[1]/article[2]/id[1] , 2