Xslt XPATH选择整个树(仅包括第一个树)
给定以下结构,在XPATH中,我希望选择整个树,但只包括第一个日期,因此排除所有其他日期。第一个日期之后的日期数不是恒定的。有什么想法吗?很抱歉,格式不正确Xslt XPATH选择整个树(仅包括第一个树),xslt,xpath,Xslt,Xpath,给定以下结构,在XPATH中,我希望选择整个树,但只包括第一个日期,因此排除所有其他日期。第一个日期之后的日期数不是恒定的。有什么想法吗?很抱歉,格式不正确 <A> <B> <DATE>04272011</DATE> <C> <D> <DATE>02022011</DATE> </
<A>
<B>
<DATE>04272011</DATE>
<C>
<D>
<DATE>02022011</DATE>
</D>
<D>
<DATE>03142011</DATE>
</D>
</C>
</B>
</A>
04272011
02022011
03142011
我的任命 更好的例子
01272011
35807
A.
地址1
02022011
12345
地址2
03022011
56789
地址3
我将把一个大的xml文件分解成单独的xml文件。我最初的XPATH语句是
/通知/通知
每个单独的xml文件看起来都很好,只是它可以提取所有的日期:这是我想要的输出
01272011
35807
A.
地址1
12345
地址2
56789
地址3
如果“选择整个树”的意思是“选择树中所有节点的集合”(非第一个日期元素除外),则可以执行以下操作:
"//node()[not(self::DATE) or not(preceding::DATE)]"
然后,非第一个
元素节点本身将不在所选节点集中,但所选节点集中的节点(如根节点或
)仍将具有子节点
相反,如果您想要选择树(即根节点),或者更确切地说是它的修改版本,使得
元素没有任何
子元素,则需要修改树。XPath本身无法修改XML树。您需要一种XML转换技术,例如XSLT或XML DOM库。如果“选择整个树”的意思是“选择树中所有节点的集合”(非第一个日期元素除外),则可以执行以下操作:
"//node()[not(self::DATE) or not(preceding::DATE)]"
然后,非第一个
元素节点本身将不在所选节点集中,但所选节点集中的节点(如根节点或
)仍将具有子节点
相反,如果您想要选择树(即根节点),或者更确切地说是它的修改版本,使得
元素没有任何
子元素,则需要修改树。XPath本身无法修改XML树。您需要XML转换技术,例如XSLT或XML DOM库。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>
<A>
<B>
<DATE>04272011</DATE>
<C>
<D/>
<D/>
</C>
</B>
</A>
在提供的XML文档上应用此转换时:
<A>
<B>
<DATE>04272011</DATE>
<C>
<D>
<DATE>02022011</DATE>
</D>
<D>
<DATE>03142011</DATE>
</D>
</C>
</B>
</A>
04272011
02022011
03142011
生成所需的正确结果:
<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>
<A>
<B>
<DATE>04272011</DATE>
<C>
<D/>
<D/>
</C>
</B>
</A>
04272011
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>
<A>
<B>
<DATE>04272011</DATE>
<C>
<D/>
<D/>
</C>
</B>
</A>
在提供的XML文档上应用此转换时:
<A>
<B>
<DATE>04272011</DATE>
<C>
<D>
<DATE>02022011</DATE>
</D>
<D>
<DATE>03142011</DATE>
</D>
</C>
</B>
</A>
04272011
02022011
03142011
生成所需的正确结果:
<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>
<A>
<B>
<DATE>04272011</DATE>
<C>
<D/>
<D/>
</C>
</B>
</A>
04272011
能否指定输出,使其更清晰?XPath 1.0还是2.0?您使用的是哪种语言的XPath(XSLT、PHP…)?告诉我们您想要实现什么可能是个好主意。有各种各样的方式来解释你说的话。一个看似无用,另一个则需要XPath本身所能做的更多。XPath可以从输入中选择节点。它无法删除或修改节点。因此,仅使用XPath无法获得所需的输出@如果可以使用XSLT,Dimitre的XSLT解决方案是一个很好的解决方案。您能指定输出,使其更清晰吗?XPath 1.0还是2.0?您使用的是哪种语言的XPath(XSLT、PHP…)?告诉我们您想要实现什么可能是个好主意。有各种各样的方式来解释你说的话。一个看似无用,另一个则需要XPath本身所能做的更多。XPath可以从输入中选择节点。它无法删除或修改节点。因此,仅使用XPath无法获得所需的输出@如果您可以使用XSLT,Dimitre的XSLT解决方案是一个很好的解决方案。谢谢。我想要从到的所有东西。有没有办法让我发布一个更好的例子,说明这个线程中的内容和原因?@HammerTime:从无到有,从
到
都包含所有
元素,所以我认为我们需要更清晰的说明。发布where和why的最好方法是编辑您的原始问题。(并添加一条带有“@LarsH”的评论让我知道。)我已经更新了我的原创,以便更好地描述我正在尝试做的事情。我知道如何选择所有内容,也知道如何只选择要排除的日期。谢谢,谢谢。我想要从到的所有东西。有什么方法可以让我发布一个更好的例子来说明这篇文章中的内容和原因吗?@HammerTime:从
到
的所有内容都将包含所有
元素,所以我想我们需要更清楚。发布where和why的最佳方式是edi