我刚开始使用xml,很难理解XSLT是如何工作的。您能帮我修复xslt文件中的一些错误吗?我想转换这个输入文件:
<?xml version="1.0" encoding="utf-8"?>
<data>
<parent><string >AAA</string></parent>
<nb><string >2</string></nb>
<child1>aaa-1</child1>
<child1>aaa-2</child1>
<parent><string >BBB</string></parent>
<nb><string>1</string></nb>
<child2>bbb-1</child2>
<parent><string >CCC</string></parent>
<nb><string >0</string></nb>
</data>转入:
<?xml version="1.0" encoding="utf-8"?>
<data>
<parent>
<string >AAA</string>
<nb><string >2</string></nb>
<child1>aaa-1</child1>
<child1>aaa-2</child1></parent>
<parent>
<string >BBB</string>
<nb><string >1</string></nb>
<child2>bbb-1</child2></parent>
<parent>
<string >CCC</string>
<nb><string >0</string></nb></parent>
</data>这些规则是:
- for each parent, I've to read the defined number ("nb") of child nodes following current parent
- when the "parent" value is 'AAA' then I've to read the "child1" 当“父”值是!=AAAA时,我必须读取"childe2“节点。
以下是我的XSLT文件,其结果与预期的不完全相同:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/">
<xsl:comment>--- </xsl:comment>
<xsl:comment>1 : parent nodes </xsl:comment>
<xsl:for-each select ="/data/parent">
<p>
<string>
<xsl:value-of select="string"/>
</string>
<xsl:comment>======================= </xsl:comment>
<xsl:comment>2 : nb nodes (how many childs for a parent ) </xsl:comment>
<xsl:for-each select ="/data/nb">
<xsl:if test="((position() < 2) and (normalize-space(position() >= 1)))">
<xsl:comment>Ex. for tThe first value only </xsl:comment>
<xsl:comment>How to do a dynamic test here (expected : AAA->3 (first nb value), BBB->1 (second nb value) ...) ?</xsl:comment>
<xsl:comment>How to synchronise loop on parent and nb ?</xsl:comment>
<nb>
<string>
<xsl:value-of select="string"/>
</string>
</nb>
</xsl:if>
</xsl:for-each>
<xsl:comment>======================= </xsl:comment>
<xsl:comment>3 : child nodes </xsl:comment>
<xsl:comment>How to manage the position and number of nodes to read ?</xsl:comment>
<xsl:comment>Test 'string =AAA' is KO : always child2 </xsl:comment>
<xsl:choose>
<xsl:when test='string =AAA'>
<xsl:copy-of select="/*/child1" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="/*/child2" />
</xsl:otherwise>
</xsl:choose>
</p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>提前感谢
诚挚的问候
发布于 2018-07-14 19:39:30
如果数据是一致的,也就是说,如果总是有nb元素所指示的nb元素的数量和parent值的任务,那么您可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:output indent="yes"/>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="parent"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent[string = 'AAA']">
<xsl:copy>
<xsl:variable name="n" select="following-sibling::nb[1]"/>
<xsl:copy-of select="string, following-sibling::nb[1], following-sibling::child1[position() <= $n]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent[string != 'AAA']">
<xsl:copy>
<xsl:variable name="n" select="following-sibling::nb[1]"/>
<xsl:copy-of select="string, following-sibling::nb[1], following-sibling::child2[position() <= $n]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>https://xsltfiddle.liberty-development.net/94hvTzk/0有这个示例,在XSLT 1中也可以这样做。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="parent"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent[string = 'AAA']">
<xsl:copy>
<xsl:variable name="n" select="following-sibling::nb[1]"/>
<xsl:copy-of select="string | following-sibling::nb[1] | following-sibling::child1[position() <= $n]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent[string != 'AAA']">
<xsl:copy>
<xsl:variable name="n" select="following-sibling::nb[1]"/>
<xsl:copy-of select="string | following-sibling::nb[1] | following-sibling::child2[position() <= $n]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>在线在https://xsltfiddle.liberty-development.net/94hvTzk/1
如果数据不一致,那么至少在XSLT2或3中,for-each-group select="*" group-starting-with="parent"在data元素的上下文中很容易识别属于一起的元素并在结果中创建parent包装器。
发布于 2018-07-15 07:48:32
使用XSLT3.0,这只是简单的
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="data">
<data>
<xsl:for-each-group select="*" group-starting-with="parent">
<parent>
<xsl:copy-of select="*, tail(current-group())"/>
</parent>
</xsl:for-each-group>
</data>
</xsl:template>
</xsl:transform>https://stackoverflow.com/questions/51340392
复制相似问题