2017-05-16 25 views
0

我已经经历了很少有关重复元素以及如何使用xsl标识模板的线程。但我的要求是重复大部分元素与几个需要转换的字段。在XSLT 2.0中获取重复元素并进行少量元素转换

这是我的输入:

<?xml version="1.0" encoding="UTF-8"?> 
<Roots xmlns="urn:com.mydish/extps"> 
    <Root> 
     <Worker>100</Worker> 
     <Group></Group> 
     <Amount>1165851.81</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>1.pdf</File_Name> 
    </Root> 
    <Root> 
     <Worker>20</Worker> 
     <Group></Group> 
     <Amount>231456.41</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>2.pdf</File_Name> 
    </Root> 
</Roots> 

输出必须是:

<?xml version="1.0" encoding="UTF-8"?> 
<Roots xmlns="urn:com.mydish/extps"> 
    <Root> 
     <Worker>C10</Worker> 
     <Group>Group1</Group> 
     <Amount>1165851.81</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>1.pdf</File_Name> 
    </Root> 
    <Root> 
     <Worker>C20</Worker> 
     <Group>Group2</Group> 
     <Amount>231456.41</Amount> 
     <Currency>USD</Currency> 
     <Check>201705091204</Check> 
     <File_Name>2.pdf</File_Name> 
    </Root> 
</Roots> 

所以,逻辑取决于输入工人长度,输出工人和组字段进行改造。

如果输入Worker长度为3位数,则输出Worker将为C,前两位数字(C10)和Group将为Group1。如果输入工作者长度是2位数,然后连接C输出Worker像(C20)和Group将是Group2。

其余部分必须与输入相同。

如何转换? 下面的一个正确吗?我知道这不会按原样工作。

<Worker> 
    <xsl:value-of select="if string-length(Worker)='3' then concat('C',substring(Worker,1,2)) else concat('C',Worker)" /> 
</Worker> 
<Group> 
    <xsl:value-of select="if string-length(Worker)='3' then 'Group1' else 'Group2'" /> 
</Group>  

回答

0

尝试下面的脚本:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="urn:com.mydish/extps" 
    xpath-default-namespace="urn:com.mydish/extps"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Worker"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length() = 3) 
     then concat('C', substring(., 1, 2)) 
     else concat('C', .)" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Group"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length(../Worker) = 3) 
     then 'Group1' else 'Group2'" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
    </xsl:template> 
</xsl:transform> 

你是相当接近正确的解决方案。

我添加了命名空间处理并对代码做了轻微的修改。

也许你应该读一点学习:

  • 关于命名空间的处理,对于的XPath表达式
  • 设置一个默认命名空间的,
  • 一个当前对象的概念(.)模板内部和 它的值是什么,
  • 如何指的是兄弟对象(例如, Worker element from Group template。
+0

谢谢,这是工作。当然,会学习你指出的主题。它确实有帮助。 – user3836593

0

对于Worker,你可以做简单:

<xsl:template match="Worker"> 
    <xsl:copy> 
     <xsl:text>C</xsl:text> 
     <xsl:value-of select="substring(., 1, 2)"/> 
    </xsl:copy> 
</xsl:template> 

对于Group,你只需要几个语法更正:

<xsl:template match="Group"> 
    <xsl:copy> 
     <xsl:value-of select="if (string-length(../Worker)=3) then 'Group1' else 'Group2'" /> 
    </xsl:copy> 
</xsl:template> 

这是除了恒等变换当然是模板。

+0

或者,对于Group使用两个模板: Group1