2011-05-03 84 views
0

我有下面的XML结构拆分XML文件复制头 - XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?> 
<ExportData> 
<TransportHeader> 
    <Timestamp>2011-01-16 06:00:33</Timestamp> 
    <From> 
     <Name>DynamicExport</Name> 
     <Version>1.</Version> 
    </From> 
    <MessageId>d7b5c5b69a83</MessageId> 
</TransportHeader> 
<ExportConfig> 
    <DateTimeFormat>yyyy-MM-dd HH:mm:ss</DateTimeFormat> 
    <DecimalSymbol>.</DecimalSymbol> 
</ExportConfig> 
<DataSet> 
    <Tables> 
     <Table> 
      <RH>...</RH> 
      <Rows> 
       <R>Data1</R> 
       <R>Data2</R> 
       <R>Data3</R> 
       <R>Data4</R> 
       <R>Data5</R> 
      </Rows> 
     </Table> 
    </Tables> 
</DataSet> 
</ExportData> 

和我需要根据<R>元素的量来分割该文件。 如果有多于3个<R>元素,则需要生成第二个输出文件。这两个文件也需要标题信息。

我想出了这个XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
xmlns:redirect="http://xml.apache.org/xalan/redirect" 
extension-element-prefixes="redirect" 
exclude-result-prefixes="xd" 
version="1.0"> 

<xsl:template match="/"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="text() | @*"/> 

<xsl:template match="Rows" name="Rows"> 
    <Rows>  
     <xsl:for-each select="R"> 
      <xsl:variable name="filename1" select="concat('output1','.xml')"/> 
      <xsl:variable name="filename2" select="concat('output2','.xml')"/> 
      <xsl:variable name="nodePosition" select="position()" /> 
      <xsl:if test="$nodePosition &lt; 3"> 
       <redirect:write select="$filename1"> 
        <xsl:copy-of select="." /> 
       </redirect:write> 
      </xsl:if> 
      <xsl:if test="$nodePosition = 3 or $nodePosition &gt; 3"> 
       <redirect:write select="$filename2"> 
         <xsl:copy-of select="." /> 
       </redirect:write> 
      </xsl:if> 
     </xsl:for-each> 
    </Rows>   
</xsl:template> 
</xsl:stylesheet> 

但是获取生成只包含“数据2”和“数据5”两个输出文件。 你能帮我弄清楚为什么其他3个数据元素丢失了吗? 如何添加标题数据?

对于标头,我想出了这个XSLT:当我把它应用到所提到的XML

<xsl:template match="//Rows"> 
    <xsl:apply-templates select="@*|Rows"/> 
</xsl:template> 

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

其中工程。但是我无法将这2个XSLT合并在一起 - 输出结果就搞砸了。

非常感谢您的帮助! 祝你好运, 彼得

+0

提供的XSLT代码甚至不是格式良好的XML。 'redirect:'前缀不绑定到任何名称空间。请改正。您似乎正在使用某种扩展元素来生成多个输出。你使用什么扩展库? – 2011-05-03 13:33:23

+0

另外,''指令缺少名称空间定义和至少一个其他必要的属性。请提供可执行的代码 - 用于复制目的,不要混淆读者。 – 2011-05-03 13:35:03

+0

你好Dimitre,谢谢你的回答。我纠正了我的错误代码。我使用XALAN作为处理器,但我不知道扩展库。 – Peter 2011-05-03 14:03:35

回答

1

此转换显示如何分裂。它作为一个练习,以使其适应您的需求:

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

<xsl:template match="R[position() mod 3 =1]"> 
    <RGroup> 
    <xsl:copy-of select= 
    ".|following-sibling::R[not(position() > 2)]"/> 
    </RGroup> 
</xsl:template> 

<xsl:template match="R"/> 
</xsl:stylesheet> 

当这个XML文档(原始提供的一个片段)上的应用:

<Rows> 
    <R>Data1</R> 
    <R>Data2</R> 
    <R>Data3</R> 
    <R>Data4</R> 
    <R>Data5</R> 
</Rows> 

想要的分裂是制备:

<Rows> 
    <RGroup> 
     <R>Data1</R> 
     <R>Data2</R> 
     <R>Data3</R> 
    </RGroup> 
    <RGroup> 
     <R>Data4</R> 
     <R>Data5</R> 
    </RGroup> 
</Rows> 
+0

你好Dimitre,谢谢你的帮助。我会根据自己的需要调整它,但一般逻辑正在起作用。我还会试着找出标题数据的问题。最好的问候,彼得 – Peter 2011-05-03 14:08:04

+0

@彼得:不客气。 – 2011-05-03 14:26:57

+0

此解决方案也可以在不复制标题数据的情况下完美工作。在我看来,它并不复杂,因此它更强大? – Peter 2011-05-17 13:28:10

1

该样式表:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:redirect="http://xml.apache.org/xalan/redirect" 
extension-element-prefixes="redirect"> 
    <xsl:strip-space elements="*"/> 
    <xsl:param name="pLimit" select="3"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:param name="pGroup"/> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"> 
       <xsl:with-param name="pGroup" select="$pGroup"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/"> 
     <xsl:for-each select="//R[position() = 1 or position() = $pLimit + 1]"> 
      <redirect:write select="concat('output',position(),'.xml')"> 
       <xsl:apply-templates select="/node()"> 
        <xsl:with-param name="pGroup" select="position()-1"/> 
       </xsl:apply-templates> 
      </redirect:write> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="R"> 
     <xsl:param name="pGroup"/> 
     <xsl:if test="position() > $pLimit = $pGroup"> 
      <xsl:call-template name="identity"/> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

output1.xml

<ExportData> 
    <TransportHeader> 
     <Timestamp>2011-01-16 06:00:33</Timestamp> 
     <From> 
      <Name>DynamicExport</Name> 
      <Version>1.</Version> 
     </From> 
     <MessageId>d7b5c5b69a83</MessageId> 
    </TransportHeader> 
    <ExportConfig> 
     <DateTimeFormat>yyyy-MM-dd HH:mm:ss</DateTimeFormat> 
     <DecimalSymbol>.</DecimalSymbol> 
    </ExportConfig> 
    <DataSet> 
     <Tables> 
      <Table> 
       <RH>...</RH> 
       <Rows> 
        <R>Data1</R> 
        <R>Data2</R> 
        <R>Data3</R> 
       </Rows> 
      </Table> 
     </Tables> 
    </DataSet> 
</ExportData> 

output2.xml

<ExportData> 
    <TransportHeader> 
     <Timestamp>2011-01-16 06:00:33</Timestamp> 
     <From> 
      <Name>DynamicExport</Name> 
      <Version>1.</Version> 
     </From> 
     <MessageId>d7b5c5b69a83</MessageId> 
    </TransportHeader> 
    <ExportConfig> 
     <DateTimeFormat>yyyy-MM-dd HH:mm:ss</DateTimeFormat> 
     <DecimalSymbol>.</DecimalSymbol> 
    </ExportConfig> 
    <DataSet> 
     <Tables> 
      <Table> 
       <RH>...</RH> 
       <Rows> 
        <R>Data4</R> 
        <R>Data5</R> 
       </Rows> 
      </Table> 
     </Tables> 
    </DataSet> 
</ExportData> 

:这是不嵌套表的简单的解决方案。使用extension-element-prefixes属性。

+0

你好亚历杭德罗,这个解决方案完美的作品。谢谢!我会看看“扩展元素前缀” - 我从来没有使用过。最好的问候,彼得 – Peter 2011-05-04 12:34:58

+0

@彼得:不客气! – 2011-05-04 12:54:03