如何打印包含其中值的xml的所有节点的Xpath

时间:2014-09-28 23:27:35

标签: xml xslt xpath

如何打印包含其中值的xml的所有节点的Xpath。 我有XSLT,它给出了所有节点的xpath,但没有检查该值。

实施例: XML:

<products author="Jesper">
  <product id="p1">
    <name>Delta</name>
    <price>800</price>
    <stock>4</stock>
    <country>Denmark</country>
  </product>
  <product id="p2">
    <name>Golf</name>
    <price>1000</price>
    <stock>5</stock>
    <country></country>
  </product>
  <product id="p3">
    <name>Alfa</name>
    <price>1200</price>
    <stock>19</stock>
    <country>Germany</country>
  </product>
  <product id="p4">
    <name>Foxtrot</name>
    <price></price>
    <stock>5</stock>
    <country>Australia</country>
  </product>
</products>

通过以下XSLT解析时:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>

        <xsl:variable name="vApos">'</xsl:variable>

        <xsl:template match="*[@* or not(*)] ">
          <xsl:if test="not(*)">
             <xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
             <xsl:text>&#xA;</xsl:text>
            </xsl:if>
            <xsl:apply-templates select="@*|*"/>
        </xsl:template>

        <xsl:template match="*" mode="path">
            <xsl:value-of select="concat('/',name())"/>
            <xsl:variable name="vnumSiblings" select=
             "count(../*[name()=name(current())])"/>
            <xsl:if test="$vnumSiblings > 1">
                <xsl:value-of select=
                 "concat('[',
                         count(preceding-sibling::*
                                [name()=name(current())]) +1,
                         ']')"/>
            </xsl:if>
        </xsl:template>

        <xsl:template match="@*">
            <xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
            <xsl:value-of select="concat('[@',name(), '=',$vApos,.,$vApos,']')"/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:template>
</xsl:stylesheet>

制作:

/products[@author='Jesper']
/products/product[1][@id='p1']
/products/product[1]/name
/products/product[1]/price
/products/product[1]/stock
/products/product[1]/country
/products/product[2][@id='p2']
/products/product[2]/name
/products/product[2]/price
/products/product[2]/stock
/products/product[2]/country
/products/product[3][@id='p3']
/products/product[3]/name
/products/product[3]/price
/products/product[3]/stock
/products/product[3]/country
/products/product[4][@id='p4']
/products/product[4]/name
/products/product[4]/price
/products/product[4]/stock
/products/product[4]/country

但我想要它产生:

/products[@author='Jesper']
/products/product[1][@id='p1']
/products/product[1]/name
/products/product[1]/price
/products/product[1]/stock
/products/product[1]/country
/products/product[2][@id='p2']
/products/product[2]/name
/products/product[2]/price
/products/product[2]/stock
/products/product[3][@id='p3']
/products/product[3]/name
/products/product[3]/price
/products/product[3]/stock
/products/product[3]/country
/products/product[4][@id='p4']
/products/product[4]/name
/products/product[4]/stock
/products/product[4]/country

请注意&#34; p2&#34;中遗漏国家/地区和价格在&#34; p4&#34;。

1 个答案:

答案 0 :(得分:0)

我自己解决了这个问题。这是它的代码。谢谢大家:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>

        <xsl:variable name="vApos">'</xsl:variable>

        <xsl:template match="*[@* or not(*)] ">
          <xsl:if test="not(*) and current()!=''">
             <xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
             <xsl:text>&#xA;</xsl:text>
            </xsl:if>
            <xsl:apply-templates select="@*|*"/>
        </xsl:template>

        <xsl:template match="*" mode="path">
            <xsl:value-of select="concat('/',name())"/>
            <xsl:variable name="vnumSiblings" select="count(../*[name()=name(current())])"/>
            <xsl:if test="$vnumSiblings > 1">
                <xsl:value-of select="concat('[',count(preceding-sibling::*[name()=name(current())]) +1,']')"/>
            </xsl:if>
        </xsl:template>

        <xsl:template match="@*">
            <xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
            <xsl:value-of select="concat('[@',name(), '=',$vApos,.,$vApos,']')"/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:template>
</xsl:stylesheet>