使用父元素在 XSLT 中拆分/分组
Split / Group in XSLT with parent elements
我正在尝试将 XML 文档拆分为固定块。
我想将此文档拆分为 n 个消息节点,其中每个节点最多包含 x(此处为 2)行元素。
我的来源是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
<line>
<content>...</content>
</line>
</Body>
</Message>
</Messages>
使用以下 XSLT,我能够创建所需的消息节点,并且还可以进行 line-spit 工作。但是我无法管理它以将所有其他元素(Control、Body、header...)复制到每个 Message 节点中。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Message">
<xsl:for-each-group select="Body/line" group-adjacent="(position() - 1) idiv 2">
<xsl:element name="Message">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
当前结果:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
</Message>
<Message>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
</Message>
<Message>
<line>
<content>...</content>
</line>
</Message>
</Messages>
但应该是:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
</Body>
</Message>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
</Body>
</Message>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>...</content>
</line>
</Body>
</Message>
</Messages>
非常感谢!
如果您知道要查找的元素的名称,最简单的方法是 select 并构建它们:
<xsl:template match="Message">
<xsl:for-each-group select="Body/line" group-adjacent="(position() - 1) idiv 2">
<Message>
<xsl:copy-of select="ancestor::Message/Control"/>
<Body>
<xsl:copy-of select="ancestor::Message/Body/*[not(self::line)], current-group()"/>
</Body>
</Message>
</xsl:for-each-group>
</xsl:template>
我正在尝试将 XML 文档拆分为固定块。 我想将此文档拆分为 n 个消息节点,其中每个节点最多包含 x(此处为 2)行元素。
我的来源是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
<line>
<content>...</content>
</line>
</Body>
</Message>
</Messages>
使用以下 XSLT,我能够创建所需的消息节点,并且还可以进行 line-spit 工作。但是我无法管理它以将所有其他元素(Control、Body、header...)复制到每个 Message 节点中。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Message">
<xsl:for-each-group select="Body/line" group-adjacent="(position() - 1) idiv 2">
<xsl:element name="Message">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
当前结果:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
</Message>
<Message>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
</Message>
<Message>
<line>
<content>...</content>
</line>
</Message>
</Messages>
但应该是:
<?xml version="1.0" encoding="UTF-8"?>
<Messages>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>ddd</content>
</line>
<line>
<content>eee</content>
</line>
</Body>
</Message>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>fff</content>
</line>
<line>
<content>ggg</content>
</line>
</Body>
</Message>
<Message>
<Control>
<ctrl1>aaa</ctrl1>
<ctrl2>...</ctrl2>
</Control>
<Body>
<header1>bbb</header1>
<header2>bbb</header2>
<header3>
<something>ccc</something>
</header3>
<line>
<content>...</content>
</line>
</Body>
</Message>
</Messages>
非常感谢!
如果您知道要查找的元素的名称,最简单的方法是 select 并构建它们:
<xsl:template match="Message">
<xsl:for-each-group select="Body/line" group-adjacent="(position() - 1) idiv 2">
<Message>
<xsl:copy-of select="ancestor::Message/Control"/>
<Body>
<xsl:copy-of select="ancestor::Message/Body/*[not(self::line)], current-group()"/>
</Body>
</Message>
</xsl:for-each-group>
</xsl:template>