Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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/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/3/heroku/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
Xml 使用XPath-如何选择/计算直接同级?_Xml_Xslt_Xpath_Count_Siblings - Fatal编程技术网

Xml 使用XPath-如何选择/计算直接同级?

Xml 使用XPath-如何选择/计算直接同级?,xml,xslt,xpath,count,siblings,Xml,Xslt,Xpath,Count,Siblings,我正在尝试将具有相同值的相邻兄弟姐妹组合在一起。但我很难只选择直系兄弟姐妹 输入: <ROWS> <ROW> <MONTH>1</MONTH> <START_DATE>15/04/2013</START_DATE> <RATE_AMOUNT>10</RATE_AMOUNT> <DISCOUNT>-2</DISCO

我正在尝试将具有相同值的相邻兄弟姐妹组合在一起。但我很难只选择直系兄弟姐妹

输入:

<ROWS>
    <ROW>
        <MONTH>1</MONTH>
        <START_DATE>15/04/2013</START_DATE>
        <RATE_AMOUNT>10</RATE_AMOUNT>
        <DISCOUNT>-2</DISCOUNT>
    </ROW>
    <ROW>
        <MONTH>2</MONTH>
        <START_DATE>15/05/2013</START_DATE>
        <RATE_AMOUNT>10</RATE_AMOUNT>
        <DISCOUNT>-2</DISCOUNT>
    </ROW>
    <ROW>
        <MONTH>3</MONTH>
        <START_DATE>15/06/2013</START_DATE>
        <RATE_AMOUNT>10</RATE_AMOUNT>
        <DISCOUNT>-5</DISCOUNT>
    </ROW>
    <ROW>
        <MONTH>4</MONTH>
        <START_DATE>15/07/2013</START_DATE>
        <RATE_AMOUNT>10</RATE_AMOUNT>
        <DISCOUNT>-2</DISCOUNT>
    </ROW>
</ROWS>

1.
15/04/2013
10
-2
2.
15/05/2013
10
-2
3.
15/06/2013
10
-5
4.
15/07/2013
10
-2
预期产出:

<RateList>
    <Rate>
        <NoOfMonths>2</NoOfMonths>
        <StartDate>15/04/2013</StartDate>
        <RateAmount>10</RateAmount>
        <Discount>-2</Discount>
    </Rate>
    <Rate>
        <NoOfMonths>1</NoOfMonths>
        <StartDate>15/06/2013</StartDate>
        <RateAmount>10</RateAmount>
        <Discount>-5</Discount>
    </Rate>
    <Rate>
        <NoOfMonths>1</NoOfMonths>
        <StartDate>15/07/2013</StartDate>
        <RateAmount>10</RateAmount>
        <Discount>-2</Discount>
    </Rate>
</RateList>

2.
15/04/2013
10
-2
1.
15/06/2013
10
-5
1.
15/07/2013
10
-2
这是我的XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <RateList>
            <xsl:apply-templates/>
        </RateList>
    </xsl:template>
    <xsl:template match="ROW">
        <xsl:variable name="noOfMonths" select=".|following-sibling::*[RATE_AMOUNT=current()/RATE_AMOUNT][DISCOUNT=current()/DISCOUNT]"/>
        <xsl:if test="not(preceding-sibling::*[RATE_AMOUNT=current()/RATE_AMOUNT][DISCOUNT=current()/DISCOUNT])"> 
            <Rate>
                <NoOfMonths>
                    <xsl:value-of select="count($noOfMonths)"/>
                </NoOfMonths>       
                <StartDate>
                    <xsl:value-of select="START_DATE"/>
                </StartDate>
                <RateAmount>
                    <xsl:value-of select="RATE_AMOUNT"/>
                </RateAmount>
                <Discount>
                    <xsl:value-of select="DISCOUNT"/>
                </Discount>
            </Rate>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

这是我得到的结果:

<RateList>
    <Rate>
        <NoOfMonths>3</NoOfMonths>
        <StartDate>15/04/2013</StartDate>
        <RateAmount>10</RateAmount>
        <Discount>-2</Discount>
    </Rate>
    <Rate>
        <NoOfMonths>1</NoOfMonths>
        <StartDate>15/06/2013</StartDate>
        <RateAmount>10</RateAmount>
        <Discount>-5</Discount>
    </Rate>
</RateList>

3.
15/04/2013
10
-2
1.
15/06/2013
10
-5
有人能帮忙吗?如何仅选择/计算直系亲属


谢谢大家!

通过直系兄弟姐妹,我只了解上面和下面的兄弟姐妹。在这种情况下,可以使用position()函数来限制。我自己刚刚开始学习,但可能是这样的

following-sibling::*[1] 

尝试以下方法(在xslt中以注释的形式进行解释):


将生成以下输出:

<?xml version="1.0"?>
<RateList>
  <Rate>
    <NoOfMonths>2</NoOfMonths>
    <StartDate>15/04/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-2</Discount>
  </Rate>
  <Rate>
    <NoOfMonths>1</NoOfMonths>
    <StartDate>15/06/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-5</Discount>
  </Rate>
  <Rate>
    <NoOfMonths>1</NoOfMonths>
    <StartDate>15/07/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-2</Discount>
  </Rate>
</RateList>

2.
15/04/2013
10
-2
1.
15/06/2013
10
-5
1.
15/07/2013
10
-2

注释:我没有使用xlt:key,因为我最喜欢的xlst处理器xsltproc不支持xls:key语句中的current()

您能使用XSLT2.0吗?这不会生成预期的输出谢谢!太完美了!很高兴我能帮忙。你能把答案标为有效吗?如果您不知道如何查看:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <RateList>
            <xsl:apply-templates select="*/ROW"/>
        </RateList>
    </xsl:template>
    <xsl:template match="ROW">

        <!--Look for preceding row which has not the same data (RATE_AMOUNT and DISCOUNT ) as the current. 
        And generate a id, here month concatenated with an '#'.-->
        <xsl:variable name="notSameData"
                  select="concat(preceding-sibling::ROW
                      [not(RATE_AMOUNT=current()/RATE_AMOUNT 
                      and DISCOUNT=current()/DISCOUNT )][1]/MONTH,'#')"/>

        <!--Count following month which has same data as current
        and also the same preceding month with not the same data as the current-->
        <xsl:variable name="noOfMonths"
                      select="count(following-sibling::*
                            [  RATE_AMOUNT=preceding-sibling::*[1]/RATE_AMOUNT and
                              DISCOUNT = preceding-sibling::*[1]/DISCOUNT]
                            [
                                  concat(preceding-sibling::ROW
                                  [not(RATE_AMOUNT=current()/RATE_AMOUNT 
                                  and DISCOUNT=current()/DISCOUNT )][1]/MONTH,'#') = $notSameData
                             ]) +1 "/>

        <!--Output only for rows which don not have a not a direct (first) preceding  one with same data.-->
        <xsl:if test="not(preceding-sibling::ROW[1][RATE_AMOUNT=current()/RATE_AMOUNT][DISCOUNT=current()/DISCOUNT])">
                <Rate>
                <NoOfMonths>
                    <xsl:value-of select="$noOfMonths"/>
                </NoOfMonths>
                <StartDate>
                    <xsl:value-of select="START_DATE"/>
                </StartDate>
                <RateAmount>
                    <xsl:value-of select="RATE_AMOUNT"/>
                </RateAmount>
                <Discount>
                    <xsl:value-of select="DISCOUNT"/>
                </Discount>
            </Rate>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
<?xml version="1.0"?>
<RateList>
  <Rate>
    <NoOfMonths>2</NoOfMonths>
    <StartDate>15/04/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-2</Discount>
  </Rate>
  <Rate>
    <NoOfMonths>1</NoOfMonths>
    <StartDate>15/06/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-5</Discount>
  </Rate>
  <Rate>
    <NoOfMonths>1</NoOfMonths>
    <StartDate>15/07/2013</StartDate>
    <RateAmount>10</RateAmount>
    <Discount>-2</Discount>
  </Rate>
</RateList>