我想在鸟类之前选择一个先于鸟类的元素,但不要选择鸟类或狗类。而且,我不知道这些元素是什么。它们可能与示例XML中的不同。而且,我想在选择变量时这样做。
输入XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<a>cat</a>
<a>dog</a>
<a>dog</a>
<a>cat</a>
<a>snake</a>
<a>cat</a>
<a>cat</a>
<a>bird</a>
<a>dog</a>
<a>cat</a>
</root>
所需的输出XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<a>cat</a>
<a>snake</a>
<a>cat</a>
<a>cat</a>
</root>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="nodes">
<xsl:copy-of select="//a"/>
</xsl:variable>
<xsl:variable name="nodeList" select="msxsl:node-set($nodes)"/>
<!-- I want to select the a elements that precede bird until I hit dog, but not select the bird or dog.
And, I don't know what the elements are. They could be different than in the sample XML.
And, I want to do it in the select of the variable below.
-->
<xsl:variable name="subsetOfNodeList" select="$nodeList/a[.='bird']/preceding-sibling::a[. >> $nodeList/a[.='bird']/preceding-sibling::a[.='dog'][1]]"/>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="$subsetOfNodeList"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
鉴于XSLT 1,我认为您可以选择bird
的前一个兄弟并且相交(记住节点集n1
和n2
的交集与$n1[count(. | $n2) = count($n2)]
完成)dog
之后的任何内容,这里有一个例子,它还使用一个键来识别dog
之后的内容:
<xsl:key name="fol" match="a[not(. = 'dog')]" use="generate-id(preceding-sibling::a[. = 'dog'][1])"/>
<xsl:template match="root">
<xsl:variable name="bird" select="a[. = 'bird']"/>
<xsl:variable name="prec-dog" select="$bird/preceding-sibling::a[. = 'dog'][1]"/>
<xsl:variable name="fol-dog" select="key('fol', generate-id($prec-dog))"/>
<xsl:variable name="prec-siblings" select="$bird/preceding-sibling::a[not(. = 'dog')]"/>
<xsl:variable name="intersect" select="$prec-siblings[count((. | $fol-dog)) = count($fol-dog)]"/>
<xsl:copy>
<xsl:copy-of select="$intersect"/>
</xsl:copy>
</xsl:template>
输入的https://xsltfiddle.liberty-development.net/eiQZDbr/2
<root>
<a id="c1">cat</a>
<a id="d1">dog</a>
<a id="d2">dog</a>
<a id="c3">cat</a>
<a id="s1">snake</a>
<a id="c4">cat</a>
<a id="c5">cat</a>
<a>bird</a>
<a>dog</a>
<a>cat</a>
</root>
我得到了结果
<root>
<a id="c3">cat</a>
<a id="s1">snake</a>
<a id="c4">cat</a>
<a id="c5">cat</a>
</root>
答案 1 :(得分:1)
可能的解决方案之一是制作&#34; initial&#34;专用电话 模板(让我们称之为打印),将最后一个元素传递给它 打印,即 bird 元素的第一个前一个兄弟(我假设 这样的 bird 元素只有一个。
此模板:
所以整个脚本可能如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template name="print">
<xsl:param name="xx"/>
<xsl:if test="$xx/text() != 'dog'">
<xsl:call-template name="print">
<xsl:with-param name="xx" select="$xx/preceding-sibling::*[1]"/>
</xsl:call-template>
<xsl:copy-of select="$xx"/>
</xsl:if>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:call-template name="print">
<xsl:with-param name="xx" select="a[text() = 'bird']/preceding-sibling::*[1]"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
</xsl:transform>