我有一个大的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
只获取名称节点
所以我一直在尝试这种类型的东西:
//项/名称/父::项目
获取名称节点及其父节点(它是项节点),但也获取名称节点的所有兄弟节点,这是我试图避免的!
非常感谢任何帮助
干杯, 标记
答案 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为您提供更小的节点集。在伪代码中:但是,如果您确定需要XML,请使用XSLT。
答案 3 :(得分:0)
您可以尝试使用or
(|
)运算符://item/name|//item/timestamp