从XML节点Java生成/获取xpath

我感兴趣的是建议/伪代码/解释,而不是实际的实现。

我想通过xml文档,及其所有节点

检查节点是否存在属性

如果节点不具有属性,get/generate String with value of its xpath

则为Case;如果节点确实具有属性,则为Case,迭代槽属性列表,并为每个属性(包括该节点)创建xpath。

忠告?希望你会提供一些有用的信息

编辑:

这样做的原因是..我正在用jmeter编写自动化测试,因此对于每个请求,我都需要验证该请求是否确实完成了工作,因此我通过使用xpath获取节点值来声明结果。(额外信息-不相关)

当请求较小时,手动创建断言不是问题,但对于较大的请求,则确实很麻烦(额外信息-不相关)

赏金:

我在寻找Java方法

目标

我的目标是从这个ex 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[1]/elemA[1]='one'

//root[1]/elemA[2]='two'

//root[1]/elemA[2][@attribute1='first']

//root[1]/elemA[2][@attribute2='second']

//root[1]/elemB[1]='three'

//root[1]/elemA[3]='four'

//root[1]/elemC[1]/elemB[1]='five'

解释:

  • 如果节点值/文本不为空/零,请获取xpath,添加=’nodevalue’以进行声明
  • 如果节点具有属性,则也为其创建断言

回答:

此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]从不显示索引。

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

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

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

<!-- 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']

以上是 从XML节点Java生成/获取xpath 的全部内容, 来源链接: utcz.com/qa/424340.html

回到顶部