我需要根据从父母/祖母的兄弟姐妹的孩子中提取的其他值来查找属性值。我认为这将采取两种不同的表达方式。
所以给定以下XML(从一个可以长达数千行的日志文件派生):
<p:log xmlns:p="urn:NamespaceInfo">
<p:entries>
<p:entry timestamp="2012-12-31T09:39:25">
<p:attributes>
<p:attrib name="Position" value="1B2" />
<p:attrib name="Something" value="Something_else" />
</p:attributes>
<p:msg>
</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:attributes>
<p:attrib name="Form" value="FormA" />
</p:attributes>
<p:msg>
</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:msg>Successful....</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T12:12:12">
<p:attributes>
<p:attrib name="Position" value="1B3" />
<p:attrib name="Something" value="Something_else" />
</p:attributes>
<p:msg>
</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:attributes>
<p:attrib name="Form" value="FormB" />
</p:attributes>
<p:msg>
</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:msg>Processing....</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:msg>Error1</p:msg>
</p:entry>
<p:entry timestamp="2012-12-31T09:39:25">
<p:msg>Error1</p:msg>
</p:entry>
</p:entries>
...
</p:log>
<p:attributes>
个父标记可以有多个<p:attrib>
子标记)<p:event>
代码只能有一个<p:msg>
代码首先,我需要获取具有相应value
属性name
的{{1}}属性的值,但前提是祖母的兄弟Position
具有一个p:entry
的孩子,文字为p:msg
。此外,它需要保持在该部分内。例如,我不希望第一次出现Error1
对,因为新的Position'/'Value
/ Position
对出现在Value
之前,即使在技术上{{1}与Error1
是两个祖父母的兄弟姐妹。
接下来,我需要我抓住的p:msg
/ Error1
孩子的父母的时间戳属性值。因此,找到位置,然后找到祖父Position
标记的时间戳属性值。
因此,对于此示例,我应该只能检索以下值:
Value
p:entry
(给出的日期/时间戳是任意值。这个是不同的,所以你知道我引用了哪一个。)
我知道有点混乱。我还需要确保只抓取一个实例,因为我使用XQuery从数据库中获取数据,每个表达式都必须产生一个奇异的值。
我可以使用以下1B3
来获取与2012-12-31T12:12:12
相关联的第一个时间戳:p:msg
但似乎无法恢复树以获得其他值。
我可以获得p:attrib grand-children的p:event事件的所有时间戳:Error1
但我似乎无法将其限制在跟随它的'Error1'之后。我不能把我的选择基于位置。我必须首先以内容为基础。
如何在日志文件的下一个实例上再次执行此操作?
(不只是第二条//p:entry[descendant::p:msg='Error1.'][1]/@timestamp
消息,下一次在日志文件中向下显示//p:entry[descendant::p:attrib[@name=''Position'']]/@timestamp)[1]
msg以显示下一个“父/兄弟”匹配项。一旦我得到上述问题的答案,这可能是显而易见的。
答案 0 :(得分:1)
<强>已更新强>:
好的,我想我得到了这个。这是第一个答案:
//p:msg[text()="Error1"]/../preceding-sibling::p:entry[./*/p:attrib[@name="Position"]][1]/*/p:attrib[@name="Position"]/@value
这是从p:msg
标记开始返回,这样可以更轻松地选择前一个父{{1}的第一个(那里是[1]
)满足条件的标签,它们有一个名为p:entry
的孙p:attrib
。
获取时间戳只是一点点简单:
Position
尝试一下,看看你的想法。
原始回答:
通常情况下,我不会发布半完成的答案,但我的猜测是你不会得到任何其他东西,因为这个问题太复杂了,所以这里是你在第一段描述的xpath:
//p:msg[text()="Error1"]/../preceding-sibling::p:entry[./*/p:attrib[@name="Position"]][1]/@timestamp
这将得到
具有相应名称属性Position的value属性的值,但仅当grand-parent的兄弟p:条目具有子句p:msg且文本为Error1时才会显示。
但是当你说“它需要留在那个部分”时,我不知道你的意思。你能澄清一下吗?这将返回//p:entry[following-sibling::p:entry/p:msg/text()="Error1"]/*/p:attrib[@name="Position"]/@value
和1B2
。
对于问题的第二部分,您可以使用以下内容获取上述条目的时间戳:
1B3
但是,这不会做你提到的“部分”事情。不幸的是,除了我(当前)对xpath的了解之外,这有点棘手。