微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 包装XML节点组

我正在使用PHP5,我需要以下面的形式转换XML:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode
        <item label="a">some text</item>
        <item label="b">some text</item>          
    </item>
</list>

进入这样的事情:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode>
        <list> <!-- opening new wrapper node-->
            <item label="a">some text</item>
            <item label="b">some text</item>
        </list> <!-- closing new wrapper node-->
    </item>
</list> 

正如您在上面所看到的,我需要为任何未被’list’节点包装的’item’节点添加一个包装器节点.

将源xml转换为目标xml有哪些可能的解决方案?

更新:

注1:任何单个或一组< item>节点需要由< list>包装节点,如果它没有包裹.

注2:需要维护内容的顺序.

注3:
如果有< item> < anotherNode>之前和之后的节点.
它应该改变这个:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <item label="a">some text</item>
        <item label="b">some text</item>          
        <anotherNode>some text</anotherNode>
        <item label="c">some text</item>
        <item label="d">some text</item>          
    </item>
</list>

进入这个:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <list> <!-- opening new wrapper node-->
            <item label="a">some text</item>
            <item label="b">some text</item>          
        </list> <!-- closing new wrapper node-->
        <anotherNode>some text</anotherNode>
        <list> <!-- opening new wrapper node-->
            <item label="c">some text</item>
            <item label="d">some text</item>
        </list> <!-- closing new wrapper node-->
    </item>
</list>

谢谢,

解决方法:

这种转变:

<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:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="item/item[1]">
  <list>
   <xsl:apply-templates mode="copy"
    select=".| following-sibling::item"/>
  </list>
 </xsl:template>

 <xsl:template match="item" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match="item/item[not(position()=1)]"/>
</xsl:stylesheet>

当应用于提供的XML文档时:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </item>
</list>

产生想要的,正确的结果:

<list>
   <item label="(1)">some text</item>
   <item label="(2)">
      <anotherNode>some text</anotherNode>
      <list>
         <item label="a">some text</item>
         <item label="b">some text</item>
      </list>
   </item>
</list>

请注意:

>使用和覆盖Identity规则.
>抑制某些元素.
>使用不同模式处理某些元素.

更新:

OP增加了额外的要求:

“如果在另一个节点之前和之后有项目元素,那么每个这样的项目元素组必须包含在一个单独的列表中”

<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:key name="kfollnonitem" match="item"
  use="generate-id(preceding-sibling::*[not(self::item)][1])"/>

 <xsl:key name="kprecnonitem" match="item"
  use="generate-id(following-sibling::*[not(self::item)][1])"/>

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

 <xsl:template match="*[not(self::list)]/item[1]">
  <list>
   <xsl:apply-templates mode="copy"
    select="key('kprecnonitem',
                 generate-id(following-sibling::*[not(self::item)][1])
                 )"/>
  </list>
 </xsl:template>

 <xsl:template match=
  "*[not(self::list) and item]/*[not(self::item)]">
  <xsl:call-template name="identity"/>

  <list>
    <xsl:apply-templates mode="copy"
     select="key('kfollnonitem', generate-id())"/>
  </list>
 </xsl:template>

 <xsl:template match="item" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match="item/item[not(position()=1)]"/>
</xsl:stylesheet>

在对XML文档执行此转换时:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <item label="a">some text</item>
        <item label="b">some text</item>
        <anotherNode>some text</anotherNode>
        <item label="c">some text</item>
        <item label="d">some text</item>
    </item>
</list>

产生了想要的正确结果:

<list>
   <item label="(1)">some text</item>
   <item label="(2)">
      <list>
         <item label="a">some text</item>
         <item label="b">some text</item>
      </list>
      <anotherNode>some text</anotherNode>
      <list>
         <item label="c">some text</item>
         <item label="d">some text</item>
      </list>
   </item>
</list>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。