Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 满足复杂条件时的模板替代_Xslt_Xpath_Xslt 1.0 - Fatal编程技术网

Xslt 满足复杂条件时的模板替代

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

我有一些语义类似于以下内容的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>
我有一些模板,如果满足某些条件,它们会覆盖行为而不做任何事情。 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>