我正在使用 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>
正如您在上面看到的,我需要向任何尚未被“列表”节点包装的“项目”节点添加一个包装器节点。
将源 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>
请注意:
身份规则的使用和覆盖。
抑制某些元素。
使用不同的模式处理某些元素。
更新:
OP 添加了额外的要求:
"如果在 anothernode
之前和之后有 item
元素,则必须包含每个这样的 item
元素组在单独的列表
中”
<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>
关于php - 包装一组 XML 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3652194/