如何在定义的点插入xml nodet

时间:2012-07-18 11:33:26

标签: xslt xslt-1.0

xslt有功能(如子串反之亦然)或如何解决?我有xml:

<document>
<Line>
    <Line-Item>
        <LineNumber>10</LineNumber>
        <EAN>111</EAN>
        <BIC>123123</BIC>
        <SIC>AVD091</SIC>
    </Line-Item>
</Line>
<Line>
    <Line-Item>
        <LineNumber>20</LineNumber>
        <EAN>22222</EAN>
        <BIC>3232332</BIC>
        <SIC>AVD25482</SIC>
    </Line-Item>
</Line>
</document>

需要输出:

10        111     123123      AVD091
20        22222   3232332     AVD25482

字段行号从1列位置开始,EAN从11列位置开始,BIC从19开始,SIC从31开始。

3 个答案:

答案 0 :(得分:2)

试试这个XSLT 1.0样式表。 pad模板是Martin的mf:pad函数的XSLT 1.0版本。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:apply-templates select="document/Line/Line-Item"/>
</xsl:template>

<xsl:template name="pad">
  <xsl:param name="value" />
  <xsl:param name="width" />
  <xsl:variable name="col-max" select="'                    '"/>
  <xsl:value-of select="substring( concat($value,$col-max), 1, $width)" /> 
</xsl:template>  

<xsl:template match="Line-Item" >

 <xsl:call-template name="pad" >
  <xsl:with-param name="value" select="LineNumber"/>
  <xsl:with-param name="width" select="10" />
 </xsl:call-template>  

 <xsl:call-template name="pad" >
  <xsl:with-param name="value" select="EAN"/>
  <xsl:with-param name="width" select="8" />
 </xsl:call-template>  

 <xsl:call-template name="pad" >
  <xsl:with-param name="value" select="BIC"/>
  <xsl:with-param name="width" select="12" />
 </xsl:call-template>  

 <xsl:value-of select="SIC" /> 

 <xsl:value-of select="'&#x0A;'" />
</xsl:template>  

<xsl:template match="*" />
</xsl:stylesheet>

答案 1 :(得分:2)

这个简短而通用的转型

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <my:fields>
  <fieldset name="LineNumber" width="10"/>
  <fieldset name="EAN" width="8"/>
  <fieldset name="BIC" width="12"/>
 </my:fields>

 <xsl:variable name="vSpaces" select="'                    '"/>

 <xsl:variable name="vFields" select="document('')/*/my:fields/*"/>

 <xsl:template match="Line-Item">
     <xsl:text>&#xA;</xsl:text>
     <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="Line-Item/*">
  <xsl:value-of select=
   "concat(.,
           substring($vSpaces,
                     1,
                      $vFields[@name = name(current())]/@width
                     -
                      string-length()
                      )
           )"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<document>
    <Line>
        <Line-Item>
            <LineNumber>10</LineNumber>
            <EAN>111</EAN>
            <BIC>123123</BIC>
            <SIC>AVD091</SIC>
        </Line-Item>
    </Line>
    <Line>
        <Line-Item>
            <LineNumber>20</LineNumber>
            <EAN>22222</EAN>
            <BIC>3232332</BIC>
            <SIC>AVD25482</SIC>
        </Line-Item>
    </Line>
</document>

会产生想要的正确结果:

10        111     123123      AVD091
20        22222   3232332     AVD25482

请注意

元素my:fields可以放在自己的XML文档中。因此,如果需要修改某些字段宽度,则不需要对XSLT代码进行任何修改。

答案 2 :(得分:1)

这是一个示例样式表(XSLT 2.0,抱歉,在您的评论表明请求1.0之前开始写作):

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf">

<xsl:param name="col-max" as="xs:string" select="'                    '"/>

<xsl:strip-space elements="*"/>
<xsl:output method="text"/>

<xsl:function name="mf:pad" as="xs:string">
  <xsl:param name="input" as="xs:string"/>
  <xsl:param name="col-length" as="xs:integer"/>
  <xsl:sequence select="concat($input, substring($col-max, 1, $col-length - string-length($input)))"/>
</xsl:function>

<xsl:template match="Line">
  <xsl:if test="position() > 1">
    <xsl:text>&#10;</xsl:text>
  </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="LineNumber">
  <xsl:sequence select="mf:pad(., 10)"/>
</xsl:template>

<xsl:template match="EAN">
  <xsl:sequence select="mf:pad(., 9)"/>
</xsl:template>

<xsl:template match="BIC">
  <xsl:sequence select="mf:pad(., 12)"/>
</xsl:template>

<xsl:template match="SIC">
  <xsl:sequence select="mf:pad(., string-length())"/>
</xsl:template>

</xsl:stylesheet>