我必须转换xml文件,我应该检查字段id'0',字段id'1'和sum字段id'2'。例如,我有:
<document>
<line id="0">
<field id="0">MAR</field>
<field id="1">doc1</field>
<field id="2">2</field>
</line>
<line id="1">
<field id="0">MAR</field>
<field id="1">doc2</field>
<field id="2">3</field>
</line>
<line id="2">
<field id="0">AAA></field>
<field id="1">doc4</field>
</line>
<line id="3">
<field id="0">MAR</field>
<field id="1">doc1</field>
<field id="2">4</field>
</line>
</document>
结果应为:
<type-MAR>
<document>doc1</document>
<sum>6</sum>
</type-MAR>
<type-MAR>
<document>doc2</document>
<sum>3</sum>
</type-MAR>
在那里我应该采用所有MAR线,并显示一些取决于字段id'1'的结果。
我的想法是,首先关闭所有循环(每个)和使用条件(何时)。也许有人提出更不合理的决定。
我添加了新笔记,如何检查数据是否如此:
<field id="0">MAR999</field>
<field id="1">doc1-1231</field>
第一个字段我尝试使用函数包含'MAR',其他字符串在' - '之前。但是当我尝试使用你的程序时,我卡住了。也许你可以为它提出一些建议吗?
答案 0 :(得分:2)
此转化:
<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:key name="kLineById0Id1" match="line[field[@id=2]]"
use="concat(field[@id=0],'+',field[@id=1])"/>
<xsl:template match=
"line[field[@id=2]
and
generate-id()
=
generate-id(key('kLineById0Id1',
concat(field[@id=0],
'+',field[@id=1])
)[1])
]
">
<xsl:element name="type-{field[@id=0]}">
<document>
<xsl:value-of select="field[@id=1]"/>
</document>
<sum>
<xsl:value-of select=
"sum(key('kLineById0Id1',
concat(field[@id=0],
'+',field[@id=1])
)
/field[@id=2]
)
"/>
</sum>
</xsl:element>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于提供的XML文档时:
<document>
<line id="0">
<field id="0">MAR</field>
<field id="1">doc1</field>
<field id="2">2</field>
</line>
<line id="1">
<field id="0">MAR</field>
<field id="1">doc2</field>
<field id="2">3</field>
</line>
<line id="2">
<field id="0">AAA></field>
<field id="1">doc4</field>
</line>
<line id="3">
<field id="0">MAR</field>
<field id="1">doc1</field>
<field id="2">4</field>
</line>
</document>
会产生想要的正确结果:
<type-MAR>
<document>doc1</document>
<sum>6</sum>
</type-MAR>
<type-MAR>
<document>doc2</document>
<sum>3</sum>
</type-MAR>
解释: Muenchian method for grouping 与定义为两个元素串联的键一起使用。
答案 1 :(得分:2)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="field[@id='1']"/>
<xsl:template match="/*">
<r>
<xsl:apply-templates select="line
[field[@id='0'] = 'MAR']
[count(
. | key('kLine', field[@id='1'])[1]
) = 1]
"/>
</r>
</xsl:template>
<xsl:template match="line">
<type-MAR>
<document>
<xsl:value-of select="field[@id='1']"/>
</document>
<sum>
<xsl:value-of select="
sum(
key('kLine', field[@id='1'])/
field[@id='2']
)"/>
</sum>
</type-MAR>
</xsl:template>
</xsl:stylesheet>
正确反对您的样本:
<r>
<type-MAR>
<document>doc1</document>
<sum>6</sum>
</type-MAR>
<type-MAR>
<document>doc2</document>
<sum>3</sum>
</type-MAR>
</r>
答案 2 :(得分:2)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kLineById0-Id1" match="line"
use="concat(field[@id='0'],'+',field[@id='1'])"/>
<xsl:param name="pId0" select="'MAR'"/>
<xsl:template match="document">
<result>
<xsl:apply-templates select="line[generate-id()=
generate-id(
key('kLineById0-Id1',
concat($pId0,
'+',
field[@id='1']
)
)[1]
)]"/>
</result>
</xsl:template>
<xsl:template match="line">
<xsl:element name="type-{$pId0}">
<document>
<xsl:value-of select="field[@id='1']"/>
</document>
<sum>
<xsl:value-of select="sum(key('kLineById0-Id1',
concat(field[@id='0'],
'+',
field[@id='1']
)
)/field[@id='2']
)"/>
</sum>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出:
<result>
<type-MAR>
<document>doc1</document>
<sum>6</sum>
</type-MAR>
<type-MAR>
<document>doc2</document>
<sum>3</sum>
</type-MAR>
</result>
注意:按@id
属性,总和组,动态元素名称进行分组,首先参数化@id。
答案 3 :(得分:0)
感谢您的回答,我使用Flack决定并做出一些修正:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kLine" match="line" use="substring(field[@id='1'],1,4)"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates select="line[contains(field[@id='0'], 'MAR')][count(. | key('kLine', substring(field[@id='1'],1,4))[1]) = 1]"/>
</document>
</xsl:template>
<xsl:template match="line">
<type-MAR>
<document>
<xsl:value-of select="substring(field[@id='1'],1,4)"/>
</document>
<sum>
<xsl:value-of select="sum(key('kLine', substring(field[@id='1'],1,4))/field[@id='2'])"/>
</sum>
</type-MAR>
</xsl:template>
</xsl:stylesheet>
Dimitre和Alejandro的决定也很好而且很有用(也许更专业)。但是Dimitre更专注于我写的任务,例如他使用条件检查我们是否有第二个字段(我没有写过,不仅MAR可以有field2)。亚历杭德罗检查它使用参数,所以对我来说,搜索更多信息如何使用它是一个很好的教训,因为使用xsl语言我有不到一个月的经验。所以对我来说很难为我的工作准备你的程序。作为初学者,Flack文本对我来说更容易理解。