レコードの数/トレーショールドとコピーヘッダーによるXMLファイルを分割-XSLT1.0
-
28-10-2019 - |
質問
次のXML構造があります
<?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>
要素2番目の出力ファイルを生成する必要があります。どちらのファイルもヘッダー情報が必要です。
私はこの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 < 3">
<redirect:write select="$filename1">
<xsl:copy-of select="." />
</redirect:write>
</xsl:if>
<xsl:if test="$nodePosition = 3 or $nodePosition > 3">
<redirect:write select="$filename2">
<xsl:copy-of select="." />
</redirect:write>
</xsl:if>
</xsl:for-each>
</Rows>
</xsl:template>
</xsl:stylesheet>
ただし、生成される2つの出力ファイルには、「data2」と「data5」のみが含まれています。他の3つのデータ要素が欠落している理由を理解するのを手伝っていただけますか?そして、どうすればヘッダーデータを追加できますか?
ヘッダーのために、私はこのXSLTを思いつきました:
<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>
これは、言及されたXMLに適用すると機能します。しかし、私は2つのXSLTを組み合わせることができませんでした - 出力はただめちゃくちゃになります。
助けてくれてありがとう!よろしく、ピーター
解決
この変換は、分割を行う方法を示しています. 。それはあなたのニーズに合わせてそれを適応させる運動として残されています:
<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>
他のヒント
このスタイルシート:
<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
属性。
所属していません StackOverflow