我有一个包含需要复制的消息和正文的命令。像这样:
<message>
<body>
<command name="1"/>
<command name="2"/>
</body>
</message>
我想要的是:
<message>
<body>
<command name="1"/>
</body>
</message>
<message>
<body>
<command name="2"/>
</body>
</message>
我正在使用以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<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:template match="/">
<xsl:variable name="items" select="/message/body/*"/>
<xsl:for-each select="$items">
<xsl:result-document href="section{position()}.xml">
<xsl:copy-of select="../../.[position()]"/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
一些澄清:名称属性不是位置属性,因此它可以变化。命令名称未知,可能会有所不同。命令本身就是节点,可以包含元素。
基于 Dabbler 的代码,我能够生成成功解析以下内容的代码:
<message>
<body>
<commandA num="1"/>
<commandB num="5"/>
<commandC num="25">
<subCommandT />
</commandC>
</body>
</message>
进入
<message>
<body>
<commandA num="1"/>
</body>
</message>
<message>
<body>
<commandB num="5"/>
</body>
</message>
<message>
<body>
<commandC num="25">
<subCommandT />
</commandC>
</body>
</message>
这是代码:
<?xml version="1.0" encoding="UTF-8"?>
<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:template match="/">
<xsl:for-each select="/message/body/*">
<xsl:apply-templates select="/*">
<xsl:with-param name="CmdId" select="generate-id(.)" tunnel="yes"/>
<xsl:with-param name="CmdPosition" select="position()" tunnel="yes"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="message">
<xsl:param name="CmdId" as="xs:string" tunnel="yes"/>
<xsl:param name="CmdPosition" as="xs:integer" tunnel="yes"/>
<xsl:result-document href="section{$CmdPosition}.xml">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:result-document>
</xsl:template>
<xsl:template match="body/*">
<xsl:param name="CmdId" as="xs:string" tunnel="yes"/>
<xsl:if test="generate-id(.) = $CmdId">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
谢谢你玩弄者!
这是原始命令的示例:
<?xml version="1.0" encoding="UTF-8"?>
<tst:Message xmlns:tst="http://www.someschema.com/v1.4" xmlns:pc="http://www.someotherschema.com/v1.5">
<tst:Body tst:hostId="1" tst:machineId="77.D2" tst:dateTimeSent="2012-07-11T15:30:46">
<tst:commandOption tst:deviceId="1" tst:dateTime="2012-07-11T15:30:46" tst:commandId="1" tst:sessionType="response" tst:sessionId="28" >
<tst:commandOptionAck tst:transactionId="12" tst:configurationId="3148"/>
</tst:commandOption>
<tst:commandOption tst:deviceId="1" tst:dateTime="2012-07-11T15:30:48" tst:commandId="2" tst:sessionType="response" tst:sessionId="29" >
<tst:commandOptionAck tst:transactionId="13" tst:configurationId="3149"/>
</tst:commandOption>
<tst:commandOption tst:deviceId="1" tst:dateTime="2012-07-11T15:30:50" tst:commandId="3" tst:sessionType="response" tst:sessionId="30" >
<tst:commandOptionAck tst:transactionId="14" />
</tst:commandOption>
<pc:pContext pc:deviceId="1" pc:dateTime="2012-07-11T15:24:17" pc:commandId="4" pc:sessionId="47146">
<pc:Exit pc:transactionId="3116380"/>
</pc:pContext>
</tst:Body>