我想以指定的格式转换下面的XML。我可以使用XSLT 2.0吗?
基本上,我想在一些元素中放置文本,并按特定顺序对新文本元素和现有子元素进行排序,因此我的xml序列化程序可以将输出xml序列化为适当的类属性。
输入XML:
<properties>
My Parent level text 1
<child1>
text1 of first child <b> in bold</b>
<childval>36-37</childval>
text2 of child <i> in italic </i>
</child1>
My Parent level text2 in <i>italic</i> also in <b>bold </b>
</properties>
预期输出XML:
<properties>
<parenttext order="1">My Parent level text 1</parenttext>
<child1 order="2">
<childtext childorder="1" > text1 of first child <b> in bold</b>
</childtext>
<childval childorder="2">36-37</childval>
<childtext childorder="3" >text2 of child <i> in italic </i>
</childtext>
</child1>
<parenttext order="3">My Parent level text2 in <i>italic</i> also in <b>bold </b>
</parenttext>
</properties>
答案 0 :(得分:1)
这是一个令人讨厌的源结构,如果你可以我首先开始在源代码中进行更改......
您可以尝试这样的事情:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes"/>
<xsl:variable name="inlineElements" select="'b','i'"/>
<xsl:template match="properties">
<properties>
<xsl:for-each-group select="node()" group-adjacent="self::text() or self::node()[name()=$inlineElements]">
<xsl:choose>
<xsl:when test="current-grouping-key()=true()">
<parenttext><xsl:copy-of select="current-group()"/></parenttext>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</properties>
</xsl:template>
<xsl:template match="child1">
<xsl:element name="{name()}">
<xsl:for-each-group select="node()" group-adjacent="self::text() or self::node()[name()=$inlineElements]">
<xsl:choose>
<xsl:when test="current-grouping-key()=true()">
<childtext><xsl:copy-of select="current-group()"/></childtext>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
<xsl:template match="childval">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这会使您想要的输出减去您的订单属性。
group-adjacent将检查所有节点并将生成相同分组键的所有内容分组在一起,直到节点生成另一个分组键。因此,文本和内联节点将生成true,直到子节点到来,这将生成false等等......
之后,您可以使用第二个转换添加订单属性:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:epub="hkda" exclude-result-prefixes="xs"
version="2.0">
<!-- copy template -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- match nodes which should have order nr -->
<xsl:template match="parrenttext | childtext | childval">
<xsl:copy>
<xsl:attribute name="orderno" select="position()"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>