我有一些复杂的xml结构。有时我想只保留与xpath条目的运行时列表匹配的元素。
示例xml
<Employee>
<Address>
<addressLine1>Dummy Line 1</addressLine1>
<zip>535270</zip>
</Address>
<Department>
<id>102</id>
<name>development</name>
</Department
</Employee>
示例xpath条目可能有点像
//Employee/Address
//Employee/Department/
//Employee/Department/name
在上面的xpath中,如果你观察到我们在部门内部有Department和Name,那么在这种情况下我可以忽略Department.Also上面的xpath条目也可以如下所示
//Employee/Address
//Employee/Department/name
我想要的结果xml如下
<Employee>
<Address>
<addressLine1>Dummy Line 1</addressLine1>
<zip>535270</zip>
</Address>
<Department>
<name>development</name>
</Department
</Employee>
我意识到我可以通过xslt实现这一目标。所以我想要xslt用于这种通用要求。我目前的代码也是在java中。在java中有没有更好的选择?
答案 0 :(得分:0)
我必须承认我并不完全理解你的要求,但我所看到的是:
我最初的反应是:使用xsl:evaluate
,但考虑到你正在使用所有XPath表达式,这可能无法为你提供所需的结果。此外,它需要一个XSLT 3.0处理器。
使用XSLT 2.0,您可以执行以下操作:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:variable name="patterns" as="xs:string*">
<xsl:sequence select="(
'foo/bar',
'foo/test',
'foo/bar/zed')" />
</xsl:variable>
<xsl:template match="node()[true() = (
for $p in $patterns
return ends-with(
string-join(current()/ancestor-or-self::*/name(),
'/'), $p))]">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
这只是为了让你开始,它不是一个完整的解决方案。它匹配生产//QName/QName
的XPath,就像您的示例中的那个。我删除了尾随//
,只是在当前路径与任何路径匹配时进行匹配(考虑到隐含的后代或自我,如示例所示)。
您可能希望将for-expression包装在函数中,并调用该函数将当前路径的串联映射到列表中的任何路径。
在当前形式中,您还需要提供通向更深路径的路径,或者您还必须实现fn:snapshot
-like function来复制祖先节点。
无论如何,我认为这是一种模仿的方法,不一定是xsl:evaluate
,而是模仿基于路径的模式匹配,正如你的问题似乎暗示的那样。