给定以下结构,在XPATH中,我想选择整个树,但只包括第一个日期,因此排除所有其他日期。第一个日期之后的日期数不是恒定的。有任何想法吗?我的道歉是格式不正确。
<A>
<B>
<DATE>04272011</DATE>
<C>
<D>
<DATE>02022011</DATE>
</D>
<D>
<DATE>03142011</DATE>
</D>
</C>
</B>
</A>
我的抱歉。
更好的例子
<NOTICES>
<SNOTE>
<DATE>01272011</DATE>
<ZIP>35807</ZIP>
<CLASSCOD>A</CLASSCOD>
<EMAIL>
<ADDRESS>address 1</ADDRESS>
</EMAIL>
<CHANGES>
<MOD>
<DATE>02022011</DATE>
<MODNUM>12345</MODNUM>
<EMAIL>
<ADDRESS>address 2</ADDRESS>
</EMAIL>
</MOD>
<MOD>
<DATE>03022011</DATE>
<MODNUM>56789</MODNUM>
<EMAIL>
<ADDRESS>address 3</ADDRESS>
</EMAIL>
</MOD>
</CHANGES>
</SNOTE>
</NOTICES>
我将一个大型xml文件分解为单个XML文件。我最初的XPATH语句是
/通知/ S注
除了拉入所有日期外,每个单独的xml文件看起来都很好:这是我想要的输出。
<SNOTE>
<DATE>01272011</DATE>
<ZIP>35807</ZIP>
<CLASSCOD>A</CLASSCOD>
<EMAIL>
<ADDRESS>address 1</ADDRESS>
</EMAIL>
<CHANGES>
<MOD>
<MODNUM>12345</MODNUM>
<EMAIL>
<ADDRESS>address 2</ADDRESS>
</EMAIL>
</MOD>
<MOD>
<MODNUM>56789</MODNUM>
<EMAIL>
<ADDRESS>address 3</ADDRESS>
</EMAIL>
</MOD>
</CHANGES>
</SNOTE>
答案 0 :(得分:3)
XPath是XML文档的查询语言,因此它不能改变文档的结构(例如插入/删除/重命名节点)。
您需要的是XSLT转换 - 就像这个简单:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DATE[preceding::DATE]"/>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<A>
<B>
<DATE>04272011</DATE>
<C>
<D>
<DATE>02022011</DATE>
</D>
<D>
<DATE>03142011</DATE>
</D>
</C>
</B>
</A>
产生了想要的正确结果:
<A>
<B>
<DATE>04272011</DATE>
<C>
<D/>
<D/>
</C>
</B>
</A>
答案 1 :(得分:1)
如果通过“选择整个树”意味着“选择树中所有节点的集合”(非第一个DATE元素除外),可以这样做:
"//node()[not(self::DATE) or not(preceding::DATE)]"
然后,非第一个<DATE>
元素节点本身不会位于所选节点集中,但所选节点集中的节点(例如根节点或<D>
)仍将具有{{ 1}}后代。
如果你想要选择树(即根节点),或者更确切地说是它的修改版本,那么<DATE>
个元素没有任何<D>
子元素,则需要修改那个树。 XPath无法自行修改XML树。您需要XML转换技术,例如XSLT或XML DOM库。