【问题标题】:How to print Xpath of all nodes of an xml which contains values in it如何打印其中包含值的xml的所有节点的Xpath
【发布时间】:2014-09-28 23:27:35
【问题描述】:

如何打印包含值的 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

请注意“p2”中省略国家和“p4”中的价格。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    我自己想出了答案。这是它的代码。不过还是谢谢大家:

    <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>
    

    【讨论】:

    • 找到你自己的答案很好,但无论如何都要回来看看——总有可能有人有更好的答案。一个建议——你不需要计算兄弟姐妹的数量来确定你是否需要[],只需检查是否存在第二个就可以了。 &lt;xsl:if test="../*[name()=name(current())][2]"/&gt;
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    相关资源
    最近更新 更多