Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.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 分组/移动具有相同属性的节点_Xml_Xslt - Fatal编程技术网

Xml 分组/移动具有相同属性的节点

Xml 分组/移动具有相同属性的节点,xml,xslt,Xml,Xslt,在stackoverflow和其他网站上阅读了5个小时后,我无法为我的问题创建解决方案。很多描述的问题和解决方案听上去都很熟悉。但不幸的是,我没能把它适应我的需要 我的初始xml文件如下所示: <document> <page> <block> <line> <span string="String1" bottom="12" /> </line> </blo

在stackoverflow和其他网站上阅读了5个小时后,我无法为我的问题创建解决方案。很多描述的问题和解决方案听上去都很熟悉。但不幸的是,我没能把它适应我的需要

我的初始xml文件如下所示:

<document>
  <page>
    <block>
      <line>
        <span string="String1" bottom="12" />
      </line>
    </block>
    <block>
      <line>
        <span string="String2" bottom="12" />
      </line>
    </block>
    <block>
      <line>
        <span string="String3" bottom="12" />
      </line>
    </block>
    <block>
      <line>
        <span string="String4" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String5" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String6" bottom="30" />
      </line>
    </block>
  </page>
  <page>
    <block>
      <line>
        <span string="String10" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String11" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String12" bottom="25" />
      </line>
    </block>
  </page>
</document>
<document>
  <page>
    <block>
      <line>
        <span string="String1" bottom="12" />
        <span string="String2" bottom="12" />
        <span string="String3" bottom="12" />
      </line>
    </block>
    <block>
      <line>
        <span string="String4" bottom="20" />
        <span string="String5" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String6" bottom="30" />
      </line>
    </block>
  </page>
  <page>
    <block>
      <line>
        <span string="String10" bottom="20" />
        <span string="String11" bottom="20" />
      </line>
    </block>
    <block>
      <line>
        <span string="String12" bottom="25" />
      </line>
    </block>
  </page>
</document>
  • 如果相等-从“楼下”复制
    span
    ,作为实际
    块/行
    节点下的最后一个节点
  • 删除“旧”节点
  • 删除整个同级,只包含
    //块/行
    ,不包含任何进一步的
    span
  • 这是寻找工作xslt的一次糟糕尝试:

    <?xml version="1.0" encoding="UTF8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="xml" indent="yes"/>
    
        <!-- Identity - copy all other data-->
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
    
    
        <xsl:template match="//block/line">
          <line>
            <xsl:apply-templates select="node()|@*" />
            <xsl:if test="parent::block/following-sibling::*[1]/line/span/@bottom = span[last()]/@bottom">
                <xsl:copy-of select="parent::block/following-sibling::*[1]/line/span" />
                <xsl:apply-templates select="parent::block/following-sibling::*[1]/*" />
            </xsl:if>
          </line>
        </xsl:template>
    
    
    </xsl:stylesheet>
    
    
    
    希望任何人都能帮忙!:-)

    在XSLT2(或3)中,您可以对每个组使用xsl:,但在XSLT1中,您可以对“Muenchian分组”使用相同的方法(使用一个键来避免在每次迭代中检查同级的性能开销)

    
    
    您肯定是被xslt 1卡住了吗(因为xslt2:-)通常我使用命令行中的
    xmlstarlet
    来翻译或测试一些东西。不幸的是,它不支持xslt2。但是使用
    xsltproc
    应该没有问题,它可以处理xslt2。因此,当有人提出xslt2解决方案时,我也会很高兴。:-)xsltproc是xslt1only@DavidCarlisle谢谢。我没有把事情搞砸。现在我在网上搜索了一个命令行linux工具。但当您不喜欢Java时,似乎没有启用xslt2的工具可用。无论是libxml2/xslproc还是xmlstarlet似乎都在计划集成:-/Thx大卫。你的解决方案很有效。看来我应该用xslt2热身了。:-)Ups会说:现在不是用xslt2热身的时候。看来我现在得睡觉了
    <?xml version="1.0" encoding="UTF8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="xml" indent="yes"/>
    
        <!-- Identity - copy all other data-->
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
    
    
        <xsl:template match="//block/line">
          <line>
            <xsl:apply-templates select="node()|@*" />
            <xsl:if test="parent::block/following-sibling::*[1]/line/span/@bottom = span[last()]/@bottom">
                <xsl:copy-of select="parent::block/following-sibling::*[1]/line/span" />
                <xsl:apply-templates select="parent::block/following-sibling::*[1]/*" />
            </xsl:if>
          </line>
        </xsl:template>
    
    
    </xsl:stylesheet>
    
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:key name="b" match="page//span" 
         use="concat(generate-id(ancestor::page[1]),' ',@bottom)"/>
    
    <xsl:template match="*">
     <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
     </xsl:copy>
    </xsl:template>
    
    <xsl:template match="page">
     <page>
      <xsl:for-each select=".//span[generate-id()=
                generate-id(key('b',
                concat(generate-id(ancestor::page[1]),' ',@bottom))[1])]">
       <block>
        <line>
         <xsl:apply-templates select="key('b',
                      concat(generate-id(ancestor::page[1]),' ',@bottom))"/>
        </line>
       </block>
      </xsl:for-each>
     </page>
    </xsl:template>
    
    </xsl:stylesheet>