xpath查询帮助,试图获取更大的XML子集

时间:2009-06-25 10:56:39

标签: xml xpath

我有一个大的XML集,我想运行一些xpath来制作一个更小的子集。 基本上,我有这种类型的布局:

<root>
  <item>
    <collection1></collection1>
    <collection2></collection2>
    <collection3></collection3>
    ...
    <collection55></collection55>
    <name>item name</name>
    <timestamp>47398743598</timestamp>
    <another1></another1>
    <another2></another2>
    ...
  </item>
  <item>
   ...
  </item>
</root>

换句话说,大量的项目节点,以及我不关心的许多其他垃圾节点。

我想运行一些xpath,将其归结为:

<root>
  <item>
    <name>item name</name>
    <timestamp>47398743598</timestamp>
  </item>
  <item>
   ...
  </item>
</root>

我目前有这种类型的东西:

// item / name

只获取名称节点

所以我一直在尝试这种类型的东西:

//项/名称/父::项目

获取名称节点及其父节点(它是项节点),但也获取名称节点的所有兄弟节点,这是我试图避免的!

非常感谢任何帮助

干杯, 标记

4 个答案:

答案 0 :(得分:4)

首先:你不能使用XPath来获取XML文档“归结为某种东西”。您可以使用它来选择节点,这就是全部。如果要更改XML文档,请使用XSLT。

这个表达式:

//item/name/parent::item

不选择“名称节点及其父节点”,它选择<name>个节点的父节点,而不选择任何其他节点。

严格地说,它选择恰好是<item>节点的父节点的所有<name>节点,该节点本身是<item>节点的子节点。当您考虑它时,这相当于只使用"//item"

无法选择节点结构。您只能选择节点列表 - 节点集。然后,您可以遍历这些节点并找出它们在文档中的位置,但节点集本身是平坦的。

我认为你需要更仔细地解释你想要做什么。我可以编写一个XSL转换,它可以执行您想要的操作,但除非我确定您的意图...; - )

编辑:

这是一种简单的XSLT 1.0方法。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="root | item | name | timestamp">
    <xsl:copy>
      <xsl:apply-templates select="*" />
      <xsl:if test="count(*) = 0">
        <xsl:value-of select="text()" />
      </xsl:if>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="* | text()" />

</xsl:stylesheet>

样品的输出(压痕矿):

<root>e
  <item>
    <name>item name</name>
    <timestamp>47398743598</timestamp>
  </item>
  <item>
   ...
  </item>
</root>

答案 1 :(得分:1)

使用XSLT,将此模板添加到identity transform

<xsl:template match="item">
   <xsl:copy>
      <xsl:apply-templates select="name | timestamp"/>
   </xsl:copy>
</xsl:template>

答案 2 :(得分:1)

Tomalak的答案很棒,如果你真的想要一个修剪过的XML文档,但有一点需要注意:他的选择模板将复制任何名称和时间戳节点,而不仅仅是项目元素下面的那些。

但是,我怀疑你并不真正想要一个精炼的XML文档,你只需要每个项目的名称和时间戳节点。根据您使用的语言,您应该能够使用xpath为您提供更小的节点集。在伪代码中:

  1. 选择“/ root / item”的xpath。这应该返回某种类型的列表。如果 你提到你的实现语言,我可以发一个简单的片段。
  2. 对于每个项目,选择时间戳和名称标签。没有理由关心其他节点。
  3. 但是,如果您确定需要XML,请使用XSLT。

答案 3 :(得分:0)

您可以尝试使用or|)运算符://item/name|//item/timestamp