0

As title

I am resarch xmlstartle, but seems no way to serach value from root node then return XPATH Is any idea?

ThanksPeter

Robber Pen
  • 1,033
  • 2
  • 12
  • 24
  • Perhaps you're after something like [this](https://stackoverflow.com/a/4747858 "Generate/get xpath from XML"), an XSLT 1.0 stylesheet. – urznow Jun 17 '22 at 16:34

1 Answers1

0

Perhaps you can make use of this example which handles elements and attributes but not other node types. Assuming a POSIX shell, indentation and line continuation characters added for readability.

xmlstarlet select --text -t \
  -m '//xsl:*/@test[contains(.,"position")]' \
    -m 'ancestor-or-self::*' \
      --var pos='1+count(preceding-sibling::*[name() = name(current())])' \
      -v 'concat("/",name(),"[",$pos,"]")' \
    -b \
    --if 'count(. | ../@*) = count(../@*)' \
      -v 'concat("/@",name())' \
    -b \
    -n \
/usr/share/*/xslt/docbook/common/db-common.xsl

Where:

  • the outer -m (--match) option specifies the target, with optional search conditions given as predicates
  • the inner -m (--match) builds the XPath of elements from root to target, calculating position by counting siblings
  • for an attribute node target - which doesn't match ancestor-or-self::* - the -i (--if) clause adjusts the XPath
  • a -C (--comp) option before -t lists the generated XSLT code

Output:

/xsl:stylesheet[1]/xsl:template[2]/xsl:for-each[1]/xsl:if[1]/@test
/xsl:stylesheet[1]/xsl:template[3]/xsl:for-each[1]/xsl:if[1]/@test
/xsl:stylesheet[1]/xsl:template[7]/xsl:for-each[1]/xsl:choose[1]/xsl:when[1]/@test
/xsl:stylesheet[1]/xsl:template[7]/xsl:for-each[1]/xsl:choose[1]/xsl:when[3]/@test

Output from outer -m '//xsl:param[string(@select)]':

/xsl:stylesheet[1]/xsl:template[1]/xsl:param[1]
/xsl:stylesheet[1]/xsl:template[4]/xsl:param[1]
/xsl:stylesheet[1]/xsl:template[5]/xsl:param[1]
/xsl:stylesheet[1]/xsl:template[5]/xsl:param[2]
/xsl:stylesheet[1]/xsl:template[6]/xsl:param[1]
urznow
  • 1,576
  • 1
  • 4
  • 13