执行以下操作的最佳(最有效)方法是什么:
考虑我有一个XML文档:
<comments question_id="123">
<comment id="1">
This is the first comment
</comment>
<comment id="2">
This is the second comment
</comment>
</comments>
现在,鉴于我指定了每个数据块的“路径”,即在这种情况下:
path: /comments/comment
我想将文档拆分为n个子部分,在本例中为2:
<comments question_id="123">
<comment id="1">
This is the first comment
</comment>
</comments>
<comments question_id="123">
<comment id="2">
This is the second comment
</comment>
</comments>
因此,基本上,我要做的是获取“/comments/comment”
生成的每个节点,同时保留所有“外部”父节点数据。
修改
注意:这需要是动态的或通用的。即以上数据xml只是一个例子。我希望能够将任何xml文档转换为此效果,给定表示每个数据节点的“路径”。其余的是xml的外部主体。
答案 0 :(得分:0)
如果你真的想用Xslt转换你的Xml,它应该是这样的:
<?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="/">
<!-- You need a document root to produce valid Xml output -->
<yourdocumentroot>
<xsl:apply-templates />
</yourdocumentroot>
</xsl:template>
<xsl:template match="comments">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="comment">
<xsl:element name="comments">
<xsl:attribute name="question_id">
<xsl:value-of select="ancestor::comments/@question_id"/>
</xsl:attribute>
<xsl:element name="comment">
<xsl:attribute name="id">
<xsl:value-of select="./@id" />
</xsl:attribute>
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
...会给你想要的输出:
<?xml version="1.0" encoding="utf-8"?>
<yourdocumentroot>
<comments question_id="123">
<comment id="1">This is the first comment</comment>
</comments>
<comments question_id="123">
<comment id="2">This is the second comment</comment>
</comments>
</yourdocumentroot>
答案 1 :(得分:0)
在我对这个问题的回答中可以找到通用的“粉碎”解决方案:https://stackoverflow.com/a/8597577/36305
以下是完整转型:
<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:param name="pLeafNodes" select="//comment"/>
<xsl:template match="/">
<t>
<xsl:call-template name="StructRepro"/>
</t>
</xsl:template>
<xsl:template name="StructRepro">
<xsl:param name="pLeaves" select="$pLeafNodes"/>
<xsl:for-each select="$pLeaves">
<xsl:apply-templates mode="build" select="/*">
<xsl:with-param name="pChild" select="."/>
<xsl:with-param name="pLeaves" select="$pLeaves"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template mode="build" match="node()|@*">
<xsl:param name="pChild"/>
<xsl:param name="pLeaves"/>
<xsl:copy>
<xsl:apply-templates mode="build" select="@*"/>
<xsl:variable name="vLeafChild" select=
"*[count(.|$pChild) = count($pChild)]"/>
<xsl:choose>
<xsl:when test="$vLeafChild">
<xsl:apply-templates mode="build"
select="$vLeafChild
|
node()[not(count(.|$pLeaves) = count($pLeaves))]">
<xsl:with-param name="pChild" select="$pChild"/>
<xsl:with-param name="pLeaves" select="$pLeaves"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="build" select=
"node()[not(.//*[count(.|$pLeaves) = count($pLeaves)])
or
.//*[count(.|$pChild) = count($pChild)]
]
">
<xsl:with-param name="pChild" select="$pChild"/>
<xsl:with-param name="pLeaves" select="$pLeaves"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<comments question_id="123">
<comment id="1">
This is the first comment
</comment>
<comment id="2">
This is the second comment
</comment>
</comments>
产生了想要的正确结果:
<t>
<comments question_id="123">
<comment id="1">
This is the first comment
</comment>
</comments>
<comments question_id="123">
<comment id="2">
This is the second comment
</comment>
</comments>
</t>