3

我需要根据从父母/祖父母的兄弟姐妹的孩子中提取的其他值来查找属性值。我认为这将需要两种不同的表达方式。

因此,给定以下 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属性为的属性的值Position,但前提是祖父母的兄弟姐妹有一个文本为p:entry的孩子。此外,它需要留在该部分内。例如,我不希望第一次出现该对,因为新的/对出现在 之前,即使从技术上讲,与 the是祖父母的兄弟姐妹。p:msgError1Position'/'ValuePositionValueError1p:msgError1

Position接下来,我需要Value我刚刚抓取的孩子的父母的时间戳属性值。p:entry所以,找到位置,然后找到祖父标签的时间戳属性值。

所以对于这个例子,我应该只能检索以下值:

1B3

2012-12-31T12:12:12 (给出的日期/时间戳是任意值。这个是不同的,所以你知道我引用的是哪一个)。

我知道有点令人困惑。我还需要确保只获取一个实例,因为我使用 XQuery 从数据库中获取数据,并且每个表达式都必须生成一个奇异值。

p:msg我可以通过以下方式获得与 with关联的第一个时间戳Error1//p:entry[descendant::p:msg='Error1.'][1]/@timestamp

但似乎无法回到树上来获取其他值。

我可以获得具有 p:attrib 孙子的 p:events 的所有时间戳://p:entry[descendant::p:attrib[@name=''Position'']]/@timestamp)[1]

但我似乎无法将其限制为仅具有“Error1”的那个。我不能根据职位进行选择。我必须首先基于内容。

奖金问题

我怎么能在日志文件的下一个实例上再次执行此操作?(不仅仅是第二Error1条消息,下一次在日志文件中Error1显示下一个“父/兄弟”匹配的消息)。一旦我得到上述问题的答案,这可能是显而易见的。

4

1 回答 1

1

更新

好的,我想我明白了。这是第一个的答案:

//p:msg[text()="Error1"]/../preceding-sibling::p:entry[./*/p:attrib[@name="Position"]][1]/*/p:attrib[@name="Position"]/@value

这是从标签开始工作p:msg这使得选择[1]前面的父p:entry标签中的第一个(即在其中)更容易,这些父标签满足他们有一个孙子的条件,即p:attribname Position

获取时间戳稍微简单一点:

//p:msg[text()="Error1"]/../preceding-sibling::p:entry[./*/p:attrib[@name="Position"]][1]/@timestamp

试试看,看看你的想法。

原始答案

通常我不会发布半成品的答案,但我猜你不会得到任何其他东西,因为这个问题是如此复杂,所以这是你在第一段中描述的 xpath:

//p:entry[following-sibling::p:entry/p:msg/text()="Error1"]/*/p:attrib[@name="Position"]/@value

这将得到

具有对应名称属性 Position 的 value 属性的值,但前提是祖父母的同级 p:entry 具有带有 Error1 文本的子 p:msg。

但是,当您说“它需要保留在该部分内”时,我不知道您的意思。你能澄清一下吗?这将返回1B21B3

对于问题的第二部分,您可以通过以下方式获取上述条目的时间戳:

//p:entry[following-sibling::p:entry/p:msg/text()="Error1" and ./*/p:attrib[@name="Position"]]/@timestamp

尽管如此,这不会做你提到的“部分”事情。不幸的是,这超出了我(当前)对 xpath 的了解,这有点棘手。

于 2012-09-25T21:58:13.877 回答