属性的最大值

时间:2010-10-21 13:14:27

标签: php xslt xpath

我想将@page <line/>的{​​{1}}属性的值更改为<section type="cover"/>的后代(max(@page) + 1) {/ 1}}。

基本上我需要封面部分的页码比内容部分的最后一个数字页码高1。

注意:<section type="contents"/>节点并不总是兄弟节点,它们可以嵌套在任何级别。

例如转换它:

<line/>

到此:

<root>
    <section type="contents">
        <line page="i">text</line> 
        <line page="ii">text</line> 
        <line page="1">text</line> 
        <line page="1">text</line> 
        <line page="2">text</line>
        <block>
            <line page="3">text</line> 
            <line page="4">text</line> 
        </block>
    </section>
    <section type="cover">
        <line page="i">text</line> 
        <line page="i">text</line> 
    </section>
</root>

有没有一种简单的方法可以通过PHP5,XSLT1.0,XPATH实现这一目标?

1 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vMax">
      <xsl:for-each select="/*/*//line/@page">
       <xsl:sort data-type="number"/>
       <xsl:if test="position() = last()">
         <xsl:value-of select="."/>
       </xsl:if>
      </xsl:for-each>
    </xsl:variable>

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

 <xsl:template match="section[@type='cover']/line/@page">
  <xsl:attribute name="page">
   <xsl:value-of select="$vMax+1"/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<root>
    <section type="contents">
        <line page="i">text</line>
        <line page="ii">text</line>
        <line page="1">text</line>
        <line page="1">text</line>
        <line page="2">text</line>
        <block>
            <line page="3">text</line>
            <line page="4">text</line>
        </block>
    </section>
    <section type="cover">
        <line page="i">text</line>
        <line page="i">text</line>
    </section>
</root>

生成想要的正确结果

<root>
   <section type="contents">
      <line page="i">text</line>
      <line page="ii">text</line>
      <line page="1">text</line>
      <line page="1">text</line>
      <line page="2">text</line>
      <block>
         <line page="3">text</line>
         <line page="4">text</line>
      </block>
   </section>
   <section type="cover">
      <line page="5">text</line>
      <line page="5">text</line>
   </section>
</root>

请注意:使用对所有page元素的line属性进行排序并获取最后一个元素的page属性,生成所需的最大值排序的节点集。

在XSLT 1.0中,出于所有实际目的,这种查找最大值或最小值的方法是最快的,尽管它的复杂度为O(N * log(N)),而有O (N)算法。一切都是不变的......