从XML节点Java生成获取xpath

从XML节点Java生成获取xpath,第1张

从XML节点Java生成/获取xpath

此XSLT转换:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:output method="text"/>    <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:value-of select="concat('=',$vApos,.,$vApos)"/>         <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="vnumPrecSiblings" select=         "count(preceding-sibling::*[name()=name(current())])"/>        <xsl:if test="$vnumPrecSiblings"> <xsl:value-of select="concat('[', $vnumPrecSiblings +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>

当应用于提供的XML文档时:

<root>    <elemA>one</elemA>    <elemA attribute1='first' attribute2='second'>two</elemA>    <elemB>three</elemB>    <elemA>four</elemA>    <elemC>        <elemB>five</elemB>    </elemC></root>

产生完全想要的正确结果:

/root/elemA='one'/root/elemA[2]='two'/root/elemA[2][@attribute1='first']/root/elemA[2][@attribute2='second']/root/elemB='three'/root/elemA[3]='four'/root/elemC/elemB='five'

当通过@ c0mrade应用于新提供的文档时:

<root>    <elemX serial="kefw90234kf2esda9231">        <id>89734</id>    </elemX></root>

再次产生正确的结果:

/root/elemX='89734'/root/elemX[@serial='kefw90234kf2esda9231']

说明:

  • 仅对没有子元素或具有属性的元素进行匹配和处理。
  • 对于任何此类元素,如果它没有子元素,则其所有祖先或自身元素都以命名为的特定模式进行处理’
    path
    ‘。然后”=’
    thevalue
    ‘“输出零件,然后输出NL字符。
  • 然后处理匹配元素的所有属性。
  • 最后,将模板应用于所有子元素。
  • 在’
    path
    ‘模式下处理元素很简单:输出一个/字符和元素名称。然后,如果前面有同名的同级兄弟,则输出“
    [numPrecSiblings + 1]
    ”部分。
  • 属性的处理很简单:首先
    ancestor-or-self::
    'path'
    模式处理其父元素的所有元素,然后输出
    [attrName = attrValue]
    部分,然后输出NL字符。

注意事项:

  • 命名空间中的名称以其初始可读形式显示,没有任何问题。
  • 为提高可读性,[1]从不显示索引。

以下是我的初步答案(可以忽略)

这是一个纯XSLT 1.0解决方案:

以下是一个示例xml文档和一个样式表,该样式表带有一个节点集参数,并为每个成员节点生成一个有效的XPath表达式。

stylesheet (buildPath.xsl):

<xsl:stylesheet version='1.0'xmlns:xsl='http://www.w3.org/1999/XSL/Transform'xmlns:msxsl="urn:schemas-microsoft-com:xslt" ><xsl:output method="text"/><xsl:variable name="theParmNodes" select="//namespace::*[local-name() ='myNamespace']"/><xsl:template match="/">  <xsl:variable name="theResult">    <xsl:for-each select="$theParmNodes">    <xsl:variable name="theNode" select="."/>    <xsl:for-each select="$theNode |$theNode/ancestor-or-self::node()[..]">      <xsl:element name="slash">/</xsl:element>      <xsl:choose>        <xsl:when test="self::*">          <xsl:element name="nodeName"> <xsl:value-of select="name()"/> <xsl:variable name="thisPosition"      select="count(preceding-sibling::*[name(current()) =   name()])"/> <xsl:variable name="numFollowing"      select="count(following-sibling::*[name(current()) =   name()])"/> <xsl:if test="$thisPosition + $numFollowing > 0">   <xsl:value-of select="concat('[', $thisPosition +    1, ']')"/> </xsl:if>          </xsl:element>        </xsl:when>        <xsl:otherwise> <!-- This node is not an element -->          <xsl:choose> <xsl:when test="count(. | ../@*) = count(../@*)">    <!-- Attribute -->   <xsl:element name="nodeName">     <xsl:value-of select="concat('@',name())"/>   </xsl:element> </xsl:when>      <xsl:when test="self::text()">  <!-- Text -->   <xsl:element name="nodeName">     <xsl:value-of select="'text()'"/>     <xsl:variable name="thisPosition"     select="count(preceding-sibling::text())"/>     <xsl:variable name="numFollowing"     select="count(following-sibling::text())"/>     <xsl:if test="$thisPosition + $numFollowing > 0">       <xsl:value-of select="concat('[', $thisPosition +     1, ']')"/>     </xsl:if>   </xsl:element> </xsl:when>      <xsl:when test="self::processing-instruction()"> <!-- Processing Instruction -->   <xsl:element name="nodeName">     <xsl:value-of select="'processing-instruction()'"/>     <xsl:variable name="thisPosition"         select="count(preceding-sibling::processing-instruction())"/>     <xsl:variable name="numFollowing"          select="count(following-sibling::processing-instruction())"/>     <xsl:if test="$thisPosition + $numFollowing > 0">       <xsl:value-of select="concat('[', $thisPosition +      1, ']')"/>     </xsl:if>   </xsl:element> </xsl:when>      <xsl:when test="self::comment()">   <!-- Comment -->   <xsl:element name="nodeName">     <xsl:value-of select="'comment()'"/>     <xsl:variable name="thisPosition"    select="count(preceding-sibling::comment())"/>     <xsl:variable name="numFollowing"    select="count(following-sibling::comment())"/>     <xsl:if test="$thisPosition + $numFollowing > 0">       <xsl:value-of select="concat('[', $thisPosition +      1, ']')"/>     </xsl:if>   </xsl:element> </xsl:when>      <!-- Namespace: --> <xsl:when test="count(. | ../namespace::*) =    count(../namespace::*)">   <xsl:variable name="apos">'</xsl:variable>   <xsl:element name="nodeName">     <xsl:value-of select="concat('namespace::*',      '[local-name() = ', $apos, local-name(), $apos, ']')"/>   </xsl:element> </xsl:when>    </xsl:choose>        </xsl:otherwise>       </xsl:choose>    </xsl:for-each>    <xsl:text>&#xA;</xsl:text>  </xsl:for-each> </xsl:variable> <xsl:value-of select="msxsl:node-set($theResult)"/></xsl:template></xsl:stylesheet>

xml source (buildPath.xml):

<!-- top level Comment --><root>    <nodeA>textA</nodeA> <nodeA id="nodeA-2">  <?myProc ?>        xxxxxxxx  <nodeB/>        <nodeB xmlns:myNamespace="myTestNamespace">  <!-- Comment within /root/nodeA[2]/nodeB[2] -->   <nodeC/>  <!-- 2nd Comment within /root/nodeA[2]/nodeB[2] -->        </nodeB>        yyyyyyy  <nodeB/>  <?myProc2 ?>    </nodeA></root><!-- top level Comment -->

结果:

/root/nodeA[2]/nodeB[2]/namespace::*[local-name() = 'myNamespace']/root/nodeA[2]/nodeB[2]/nodeC/namespace::*[local-name() ='myNamespace']


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5166042.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存