Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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 结合Kayessian交点和Muenchian分组_Xslt_Xslt 1.0 - Fatal编程技术网

Xslt 结合Kayessian交点和Muenchian分组

Xslt 结合Kayessian交点和Muenchian分组,xslt,xslt-1.0,Xslt,Xslt 1.0,我有一个非常简单的文档,其中包含基于标题项后位置的隐含元素组: <Document> <Body> ... <Heading>Section 1</Heading> <Item Id="1.1">Alpha</Item> <Item Id="1.1">Bravo</Item> ... <Hea

我有一个非常简单的文档,其中包含基于
标题
项后位置的隐含元素组:

<Document>
    <Body>
        ...
        <Heading>Section 1</Heading>
        <Item Id="1.1">Alpha</Item>
        <Item Id="1.1">Bravo</Item>
        ...
        <Heading>Section 2</Heading>
        <Item Id="2.1">Alpha</Item>
        <Item Id="2.1">Bravo</Item>
        ...
    </Body>
</Document>
该节点集是两个节点集的交点:标题“第1节”(包括标题本身)之后的所有元素和标题“附录B”之前的所有元素

这与我所关心的元素相匹配,但是由于键是未过滤的,因此给定标识符的“first”值有时不在该节点集的范围内。我曾尝试在键中使用变量,但后来发现键中的匹配存在许多限制,这些限制阻止了变量的使用

以下是完整的源文件:

<Document>
    <Body>

        <Heading>Preamble</Heading>
        <Para>
            Lorem ipsum dolor sit amet, consectetur
            adipiscing elit, sed do eiusmod tempor incididunt
            ut labore et dolore magna aliqua.
        </Para>

        <Heading>Example</Heading>
        <Item Id="1.1">Example Alpha</Item>
        <Item Id="1.1">Example Bravo</Item>

        <Heading>Section 1</Heading>
        <Item Id="1.1">Alpha</Item>
        <Item Id="1.1">Bravo</Item>
        <Item Id="1.2">Charlie</Item>
        <Item Id="1.3">Delta</Item>
        <Item Id="1.3">Echo</Item>
        <Item Id="1.4">Foxtrot</Item>

        <Heading>Section 2</Heading>
        <Item Id="2.1">Alpha</Item>
        <Item Id="2.1">Bravo</Item>
        <Item Id="2.2">Charlie</Item>
        <Item Id="2.3">Delta</Item>
        <Item Id="2.3">Echo</Item>
        <Item Id="2.4">Foxtrot</Item>

        <Heading>Appendix A</Heading>
        <Item Id="A.1">Alpha</Item>
        <Item Id="A.1">Bravo</Item>
        <Item Id="A.2">Charlie</Item>
        <Item Id="A.3">Delta</Item>
        <Item Id="A.3">Echo</Item>
        <Item Id="A.4">Foxtrot</Item>

        <Heading>Appendix B</Heading>
        <Para>
            Lorem ipsum dolor sit amet, consectetur
            adipiscing elit, sed do eiusmod tempor incididunt
            ut labore et dolore magna aliqua.
        </Para>

    </Body>
</Document>

序言
洛雷姆·伊普苏姆·多洛·希特·阿梅特,康塞特图
高级工程师,临时工程师
我们的劳动和财富都是巨大的。
例子
示例Alpha
示例B
第一节
阿尔法
布拉沃河
查理
三角洲
回音
狐步舞
第二节
阿尔法
布拉沃河
查理
三角洲
回音
狐步舞
附录A
阿尔法
布拉沃河
查理
三角洲
回音
狐步舞
附录B
洛雷姆·伊普苏姆·多洛·希特·阿梅特,康塞特图
高级工程师,临时工程师
我们的劳动和财富都是巨大的。
我将应用以下样式表:

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- The node-set which covers the wanted section of elements. -->
    <xsl:variable
        name="section"
        select="(/Document/Body/Heading[text() = 'Example']
            /following-sibling::*[2]/following-sibling::*)[
        count(. | /Document/Body/Heading[text() = 'Appendix B']
            /preceding-sibling::*) 
        = count(/Document/Body/Heading[text() = 'Appendix B']
            /preceding-sibling::*)
        ]" />

    <!-- The items keyed by their ID. -->
    <xsl:key
        name="ItemsById"
        match="/Document/Body/Item"
        use="@Id"/>

    <!-- Matches the root to begin the output structure. -->
    <xsl:template match="/">
        <Document>
            <!-- Apply templates to the headings. -->
            <xsl:apply-templates select="$section[local-name() = 'Heading']" />
        </Document>
    </xsl:template>

    <xsl:template match="/Document/Body/Heading">
        <Section>
            <xsl:attribute name="Title">
                <xsl:value-of select="."/>
            </xsl:attribute>

            <xsl:variable
                name="heading"
                select="generate-id()" />

            <!-- Apply templates to the items in this set. -->
            <xsl:apply-templates
                select="$section[
                local-name() = 'Item'
                and
                generate-id() = generate-id(key('ItemsById', @Id)[1])
                and
                $heading = generate-id(preceding-sibling::Heading[1])
                ]" />
        </Section>
    </xsl:template>

</xsl:stylesheet>

这是电流输出:

<Document>
  <Section Title="Section 1">
    <Item Id="1.2">Charlie</Item>
    <Item Id="1.3">Delta</Item>
    <Item Id="1.4">Foxtrot</Item>
  </Section>
  <Section Title="Section 2">
    <Item Id="2.1">Alpha</Item>
    <Item Id="2.2">Charlie</Item>
    <Item Id="2.3">Delta</Item>
    <Item Id="2.4">Foxtrot</Item>
  </Section>
  <Section Title="Appendix A">
    <Item Id="A.1">Alpha</Item>
    <Item Id="A.2">Charlie</Item>
    <Item Id="A.3">Delta</Item>
    <Item Id="A.4">Foxtrot</Item>
  </Section>
</Document>

查理
三角洲
狐步舞
阿尔法
查理
三角洲
狐步舞
阿尔法
查理
三角洲
狐步舞
问题是第1节缺少第1.1项

在我感兴趣的部分中,我可以尝试实现相同的分组吗?

这难道不能(更)简单吗?例如,以下样式表:

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- The node-set which covers the wanted section of elements. -->
    <xsl:variable
        name="section"
        select="(/Document/Body/Heading[text() = 'Example']
            /following-sibling::*[2]/following-sibling::*)[
        count(. | /Document/Body/Heading[text() = 'Appendix B']
            /preceding-sibling::*) 
        = count(/Document/Body/Heading[text() = 'Appendix B']
            /preceding-sibling::*)
        ]" />

    <!-- The items keyed by their ID. -->
    <xsl:key
        name="ItemsById"
        match="/Document/Body/Item"
        use="@Id"/>

    <!-- Matches the root to begin the output structure. -->
    <xsl:template match="/">
        <Document>
            <!-- Apply templates to the headings. -->
            <xsl:apply-templates select="$section[local-name() = 'Heading']" />
        </Document>
    </xsl:template>

    <xsl:template match="/Document/Body/Heading">
        <Section>
            <xsl:attribute name="Title">
                <xsl:value-of select="."/>
            </xsl:attribute>

            <xsl:variable
                name="heading"
                select="generate-id()" />

            <!-- Apply templates to the items in this set. -->
            <xsl:apply-templates
                select="$section[
                local-name() = 'Item'
                and
                generate-id() = generate-id(key('ItemsById', @Id)[1])
                and
                $heading = generate-id(preceding-sibling::Heading[1])
                ]" />
        </Section>
    </xsl:template>

</xsl:stylesheet>
XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="item-by-heading" match="Item" use="generate-id(preceding-sibling::Heading[1])" />
<xsl:key name="item-by-id" match="Item" use="concat(generate-id(preceding-sibling::Heading[1]), '|', @Id)" />

<xsl:template match="/Document">
    <xsl:copy>
        <xsl:apply-templates select="Body/Heading"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Heading">
    <Section Title="{.}">
        <xsl:copy-of select="key('item-by-heading', generate-id())[count(. | key('item-by-id', concat(generate-id(preceding-sibling::Heading[1]), '|', @Id))[1]) = 1]"/>
    </Section>
</xsl:template> 

</xsl:stylesheet>

应用于输入时,将返回:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
   <Section Title="Preamble"/>
   <Section Title="Example">
      <Item Id="1.1">Example Alpha</Item>
   </Section>
   <Section Title="Section 1">
      <Item Id="1.1">Alpha</Item>
      <Item Id="1.2">Charlie</Item>
      <Item Id="1.3">Delta</Item>
      <Item Id="1.4">Foxtrot</Item>
   </Section>
   <Section Title="Section 2">
      <Item Id="2.1">Alpha</Item>
      <Item Id="2.2">Charlie</Item>
      <Item Id="2.3">Delta</Item>
      <Item Id="2.4">Foxtrot</Item>
   </Section>
   <Section Title="Appendix A">
      <Item Id="A.1">Alpha</Item>
      <Item Id="A.2">Charlie</Item>
      <Item Id="A.3">Delta</Item>
      <Item Id="A.4">Foxtrot</Item>
   </Section>
   <Section Title="Appendix B"/>
</Document>

示例Alpha
阿尔法
查理
三角洲
狐步舞
阿尔法
查理
三角洲
狐步舞
阿尔法
查理
三角洲
狐步舞
我不明白您如何确定要在输出中包括(或排除)哪些部分,但这也应该很容易


编辑: 我想要的部分是第1-2节和附录A;没有其他章节 这些都是相关的

好吧,那就做:

<xsl:template match="/Document">
    <xsl:copy>
        <xsl:apply-templates select="Body/Heading[.='Section 1' or .='Section 2'or .='Appendix A']"/>
    </xsl:copy>
</xsl:template>

注意,如果项目ID没有跨节复制,那么这可能会更简单。啊,但我看到他们是。这就是第1.1项缺失的原因


编辑2: 此节点集是两个节点集的交点:所有元素 在标题“第1节”(包括标题本身)和所有 标题“附录B”前的要素

好吧,那么:

<xsl:template match="/Document">
    <xsl:copy>
        <xsl:apply-templates select="Body/Heading[.='Section 1' or preceding-sibling::Heading[.='Section 1'] and following-sibling::Heading[.='Appendix B']]"/>
    </xsl:copy>
</xsl:template>

或者更简短地说:

<xsl:template match="/Document">
    <xsl:copy>
        <xsl:apply-templates select="Body/Heading[not(following-sibling::Heading[.='Section 1']) and following-sibling::Heading[.='Appendix B']]"/>
    </xsl:copy>
</xsl:template>


问得好,问得好。确定您仅限于XSLT1.0吗?我在.NET下运行,很遗憾是的。文档有多大?你有多关心表现?有很多方法不用钥匙,但速度会慢得多。(顺便说一句,很遗憾.NET只支持1.0…)。文档大小为8Mb,但性能不是优先考虑的。Fast很好,但不是必须的。对不起,这还不清楚。你是指示例和附录B之间的任何部分,不包括这两个部分吗?我想要的部分是第1-2节和附录A;没有其他相关章节。在我的
部分
变量中,我仅限于这些。如果我的示例中不清楚,我很抱歉;我之所以使用节点集,是因为节的数量非常大,并且恰好由文档中的两个位置分隔,因此我应用了交集。“明确地识别它们是不切实际的。”悲剧者我的问题是我无法阅读你的样式表;所以,如果你能编辑你的问题,用你自己的话解释应该包括哪些部分……我已经更新了问题的细节,尽管我不确定我是否已经说得更清楚了。我真的很喜欢你采用的复合键方法,所以我会稍微处理一下。@Tragedian我相信你做到了-看看我的第二次编辑是否切中要害。
<xsl:template match="/Document">
    <xsl:copy>
        <xsl:apply-templates select="Body/Heading[not(following-sibling::Heading[.='Section 1']) and following-sibling::Heading[.='Appendix B']]"/>
    </xsl:copy>
</xsl:template>