1

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 开始。

4

3 回答 3

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>
于 2012-07-18T12:39:55.680 回答
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 代码。

于 2012-07-18T12:44:35.273 回答
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>
于 2012-07-18T12:14:10.307 回答