Xslt 满足复杂条件时的模板替代
我有一些语义类似于以下内容的XML:Xslt 满足复杂条件时的模板替代,xslt,xpath,xslt-1.0,Xslt,Xpath,Xslt 1.0,我有一些语义类似于以下内容的XML: <root> <parent> <a> <b t="0"/> </a> <a> <b t="0"/> </a> <a so="2"> <b t="1"> <c n="x"/> </b> </a&g
<root>
<parent>
<a>
<b t="0"/>
</a>
<a>
<b t="0"/>
</a>
<a so="2">
<b t="1">
<c n="x"/>
</b>
</a>
<a>
<b t="2">
<c n="x"/>
</b>
</a>
<a>
<b t="1">
<c n="y"/>
</b>
</a>
<a so="3">
<b t="2">
<c n="z"/>
</b>
</a>
</parent>
<parent>
<a so="1">
<b t="2">
<c n="x"/>
</b>
</a>
<a so="4">
<b t="1">
<c n="z"/>
</b>
</a>
</parent>
</root>
我有一些模板,如果满足某些条件,它们会覆盖行为而不做任何事情。
e、 g:
(注意:在上述示例中,文件顺序很重要,但在下面的问题中,文件顺序并不重要)
这很有效,但是现在我需要做一些更复杂的事情。
考虑到满足以下条件,我想忽略上述示例xml中的第4个元素:
b/@t=“2”
- 在同一父元素中还有一些其他的
a
,其中b/@t=“1”
- 两个
a
元素的b/c/@n
值相同
在示例xml中,最后一个节点不应与此规则匹配,因为@n的值不同
我不在乎a
节点的顺序,也不在乎中间是否有其他东西。但是,我可以声明,如果需要,节点将按所示顺序排列,没有中间节点
除了模板重写之外,可能还有其他方法来实现这一点,但是为了代码整洁,我真的在寻找一个基于模板的解决方案(如果有的话)
我目前正在使用xmlstarlet,它不支持XSLT2.0或XPATH2.0,我可以研究其他引擎,但如果可能的话,我更愿意使用我现有的引擎
注意:不同父节点中的节点不应相互影响-例如,标记为@so=1
的节点不应受到标记为@so=2
的节点的影响,因为它们位于不同的父节点中。
同样适用于@so=3
和@so=4
。在本例中,这些节点都不应匹配以下XSLT片段根据请求删除了第4个a
:
<!-- all a keyed by the value of b/@t -->
<xsl:key name="k1" match="//parent/a" use="b/@t"/>
<xsl:template match="//parent/a[b/@t = 2 and
key('k1', 1)/b/c/@n = b/c/@n]"/>
后一个XSLT脚本转换以下XML:
<root>
<parent>
<a> <b t="0"/></a>
<a> <b t="0"/></a>
<a so="2"><b t="1"><c n="x"/></b></a>
<a> <b t="2"><c n="x"/></b></a>
<a> <b t="1"><c n="y"/></b></a>
<a so="3"><b t="2"><c n="z"/></b></a>
</parent>
<parent>
<a so="1"><b t="2"><c n="x"/></b></a>
<a so="4"><b t="1"><c n="z"/></b></a>
</parent>
</root>
进入
上次我试着用钥匙时头疼!然后我甚至忘记了它的存在。这是否解释了不同的context
元素?双方之间不应进行交叉检查them@DJL:因此,当添加包含
的第二个上下文元素时,它应该保持不变?否,这将被删除。请你更新问题以澄清一下好吗?也许添加第二个上下文元素?我认为这涵盖了“在同一上下文元素中”。我将编辑到clarify@DJL是的,你说得对。我在阅读问题时忽略了这一点。不过,也许您可以使用我更新的答案中的XML更新示例XML。如果它是正确的,那就是。
<!-- all a keyed by the value of b/@t -->
<xsl:key name="k1" match="//parent/a" use="b/@t"/>
<xsl:template match="//parent/a[b/@t = 2 and
key('k1', 1)/b/c/@n = b/c/@n]"/>
<!-- all a keyed by parent node and the value of b/@t -->
<xsl:key name="k1" match="//parent/a" use="concat(generate-id(..),'|',b/@t)"/>
<xsl:template match="//parent/a[b/@t = 2 and
key('k1', concat(generate-id(..),'|',1))/b/c/@n = b/c/@n]"/>
<root>
<parent>
<a> <b t="0"/></a>
<a> <b t="0"/></a>
<a so="2"><b t="1"><c n="x"/></b></a>
<a> <b t="2"><c n="x"/></b></a>
<a> <b t="1"><c n="y"/></b></a>
<a so="3"><b t="2"><c n="z"/></b></a>
</parent>
<parent>
<a so="1"><b t="2"><c n="x"/></b></a>
<a so="4"><b t="1"><c n="z"/></b></a>
</parent>
</root>
<root>
<parent>
<a> <b t="0"/></a>
<a> <b t="0"/></a>
<a so="2"><b t="1"><c n="x"/></b></a>
<a> <b t="1"><c n="y"/></b></a>
<a so="3"><b t="2"><c n="z"/></b></a>
</parent>
<parent>
<a so="1"><b t="2"><c n="x"/></b></a>
<a so="4"><b t="1"><c n="z"/></b></a>
</parent>
</root>