之前可能会问过这个问题,但我有一个XML文件需要拆分成单独的文件。
文件是:
<?xml version="1.0" encoding="UTF-8"?>
<invoices>
<invoice>
<data>
</data>
</invoice>
<invoice>
<data>
</data>
</invoice>
</invoices>
我有我的代码将其拆分为:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" exclude-result-prefixes="xsl">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="no" indent="yes"/>
<xsl:template match="/">
<tosplit>
<xsl:for-each-group select="//invoice" group-by="ceiling(position() div 1)">
<xsl:apply-templates select="/" mode="copy">
<xsl:with-param name="currentgroup" select="current-group()"/>
</xsl:apply-templates>
</xsl:for-each-group>
</tosplit>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:param name="currentgroup"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy">
<xsl:with-param name="currentgroup" select="current-group()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="invoices" mode="copy">
<xsl:param name="currentgroup"/>
<xsl:copy>
<xsl:apply-templates select="@*" mode="copy"/>
<xsl:apply-templates select="$currentgroup" mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
然而,这并不能解决问题。我希望每个文件看起来像
<?xml version="1.0" encoding="UTF-8"?>
<tosplit>
<invoices>
<invoice>
<data>
</data>
</invoice>
</invoices>
</tosplit>
任何帮助将不胜感激。
答案 0 :(得分:0)
如果您可以访问oXygen中的Saxon 9 PE或EE等XSLT 3.0处理器或XMLSpy 2017中的Altova's Raptor,那么您只需要
public static bool HasClass(this HtmlNode node, params string[] classValueArray)
{
var classValue = node.GetAttributeValue("class", "");
var classValues = classValue.Split(' ');
return classValueArray.All(c => classValues.Contains(c));
}
为每个<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:mode on-no-match="shallow-skip" streamable="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="invoice">
<xsl:result-document href="invoice-split{position()}.xml">
<xsl:copy-of select="snapshot(.)/root()"/>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
元素创建一个结果文档。
答案 1 :(得分:0)
让我们先看看你的代码无效的原因
<xsl:template match="/">
<tosplit>
<xsl:for-each-group select="//invoice" group-by="ceiling(position() div 1)">
<xsl:apply-templates select="/" mode="copy">
<xsl:with-param name="currentgroup" select="current-group()"/>
</xsl:apply-templates>
</xsl:for-each-group>
</tosplit>
</xsl:template>
我真的不知道你对那个分组属性的想法。如果X是一个整数(因为position()是),那么ceiling(X div 1)
将返回X不变。所以它与group-by =“position()”相同,并且由于每个项目的位置不同,每个项目将进入一个单独的组。这意味着您的代码是一种令人费解的方式:
<xsl:template match="/">
<tosplit>
<xsl:for-each select="//invoice" >
<xsl:apply-templates select="/" mode="copy">
<xsl:with-param name="currentgroup" select="."/>
</xsl:apply-templates>
</xsl:for-each>
</tosplit>
</xsl:template>
反过来又无法实现任何无法自然完成的事情
<xsl:template match="/">
<tosplit>
<xsl:apply-templates select="//invoice" mode="copy"/>
</tosplit>
</xsl:template>
基本上,你没有进行任何分组,从你的问题陈述中你不需要进行任何分组,因此很难看出这段代码是什么。
同时,您说您希望为每个发票生成一个文件,但您的代码不会尝试生成多个输出文件。