2009-06-25 53 views
0

我有一个很大的XML集,我想运行一些xpath来制作一个更小的子集。 基本上,我有这种类型的布局:xpath查询帮助,试图获取更大的XML的子集

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

我目前这种类型的事情:

//项目/名称

只得到名称节点,

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

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

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

任何帮助,将不胜感激

干杯, 马克

回答

4

第一关:你不能使用XPath获得一个XML文件“归结为某件事”。你可以用它来选择节点,就这些了。如果您想更改XML文档,请使用XSLT。

这个表达式:

//item/name/parent::item 

没有选择“的名字节点,它的父”,它选择<name>节点的父节点,而不是其他。

严格来说,它选择所有<item>节点,它们恰好是<item>节点的子节点的<name>节点的父节点。当您考虑时,相当于只使用"//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> 
0

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

+0

这实际上只是返回名称和时间戳节点,虽然它是我之后的东西,我会理想地喜欢它们包裹在他们的父节点节点 – Mark 2009-06-25 11:13:34

+0

对不起,我认为主要问题是获取子节点。不幸的是,使用单个XPath是不可能的;它只是选择节点,并不修剪它们。您需要使用XSLT:选择项目的一个模板,以及仅选择名称和时间戳的一个(或子表达式)。 – l0b0 2009-06-25 12:04:40

1

使用XSLT,这个模板添加到identity transform

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

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

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

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

但是,如果您确定需要XML,请使用XSLT。