避免在XSL中进行双重计算

时间:2014-12-18 15:11:06

标签: xml xslt

我正在进行XSLT转换。我对XSLT来说还是比较新的,而且我对它有些麻烦,说得温和一点。我正在研究一些输入,并根据一些计算(检查多边形的交叉点,这需要花费大量时间,因为数据量很大),我想在集合中添加一些元素。

在输出结束时,我想要一个指示器,说明该列表是否包含元素 - 非常简单,但仍然有问题。我发现它无法访问转换中的初步生成数据,因为显然只有输入可用。

这是我的意见。请注意,此输入可以重复多次,因此转换会迭代所有" IterationResponses"。

    <IterationResponse Iteration="0">
    <QueryResult>
        <Collection>
            <Element>
                <Name>City1</Name>
                <number>151</number>
                <Link>Link1</Link>
                <GMLData>[massive data amount]</GMLData>
            </Element>
            <Element>
                <Name>City1</Name>
                <number>151</number>
                <Link>Link2</Link>
                <GMLData>[massive data amount]</GMLData>
            </Element>
            <Element>
                <Name>City2</Name>
                <number>190</number>
                <Link>Link3</Link>
                <GMLData>[massive data amount]</GMLData>
            </Element>
            <Element>
                <Name>City3</Name>
                <number>163</number>
                <Link>Link4</Link>
                <GMLData>[massive data amount]</GMLData>
            </Element>
        </Collection>
    </QueryResult>
    <Selection>
        <cadastral>
            <cadastralPolygon>
                <Polygon>
                    <exterior>
                        <LinearRing>
                            <posList>[small amount of data]</posList>
                        </LinearRing>
                    </exterior>
                </Polygon>
            </cadastralPolygon>
        </cadastral>
    </Selection>
</IterationResponse>

这是我目前的转型(简化很多,因为实际输入,转换和输出很大,但问题仍然存在)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                              xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
                              xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:variable name="var_bufferWidth" select="'-0.5'" />

        <QueryResult>
            <xsl:choose>
                <xsl:when test="count(//Error) >= 1">
                <!-- Error handling -->
                </xsl:when>
                <xsl:otherwise>      
                    <Overview>
                        <OverviewCollection>
                            <!--Iterate all iteration responses--> 
                            <xsl:for-each select="//IterationResponse">
                                <xsl:variable name="cadastralGML" select="Selection/cadastral/cadastralPolygon"/>
                                <xsl:for-each select=".//Element">
                                    <xsl:if test="func:Conflicts($cadastralGML, GMLData, $var_bufferWidth)">
                                        <OverviewElement>
                                            <Number>
                                                <xsl:value-of select="concat('0',Kommunenummer)"/>
                                            </Number>
                                            <Name>
                                                <xsl:value-of select="Name"/>
                                            </Name>
                                            <Reference>
                                                <xsl:value-of select="Link"/>
                                            </Reference>
                                        </OverviewElement>
                                    </xsl:if>
                                </xsl:for-each>
                            </xsl:for-each>
                        <OverviewCollection>
                        <OverviewIndicator>
                          <xsl:value-of select="count(/*//OverviewElement) > 0"/>
                        <OverviewIndicator>
                    </Overview>
                </xsl:otherwise>
            </xsl:choose>
        </QueryResult>
</xsl:template>

这是我目前的输出。

<Overview>
  <OverviewCollection>
    <OverviewElement>
      <Number>0151</Number>
      <Name>City1</Name>
      <Reference>Link1</Reference>
    </OverviewElement>
  </OverviewCollection>
  <OverviewIndicator>false</OverviewIndicator>
</Overview>

而不是假,我希望它是真的,因为最终的集合不是空的。非常感谢任何帮助!

提前致谢。

1 个答案:

答案 0 :(得分:2)

正如Martin Honnen所指出的,您可以使用node-set()函数来访问在XSLT中生成的节点。

您需要声明EXSL命名空间:

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

捕获变量中的输出:

<xsl:variable name="overviewCollection">
  <OverviewCollection>
    <!--Iterate all iteration responses-->
    <xsl:for-each select="//IterationResponse">
      ...
    </xsl:for-each>
  </OverviewCollection>
</xsl:variable>

输出:

<xsl:copy-of select="$overviewCollection" />

根据需要使用变量:

<OverviewIndicator>
  <xsl:value-of 
      select="boolean(exsl:node-set($overviewCollection)//OverviewElement)"/>
</OverviewIndicator>

以下是所有组合在一起的内容:

<Overview>
  <xsl:variable name="overviewCollection">
    <OverviewCollection>
      <!--Iterate all iteration responses-->
      <xsl:for-each select="//IterationResponse">
        ...
      </xsl:for-each>
    </OverviewCollection>
  </xsl:variable>
  <xsl:copy-of select="$overviewCollection" />
  <OverviewIndicator>
    <xsl:value-of 
        select="boolean(exsl:node-set($overviewCollection)//OverviewElement)"/>
  </OverviewIndicator>
</Overview>