本文介绍了XSLT转换从元素创建新的qnames的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要转换xml输出中包含的数据表,如下所示。
C1 column 1 c2 column2 etc

 <?xml version =1.0encoding =UTF-8 ?> 
< report>
< report_header>
< c1> desc< / c1>
< c2> prname< / c2>
< c3> prnum< / c3>
< c4> cdate< / c4>
< c5>阶段< / c5>
< c6> stype< / c6>
< c7>状态< / c7>
< c8> parent< / c8>
< c9>位置< / c9>
< / report_header>
< report_row>
< c1>< / c1>
< c2> IT项目消息验证< / c2>
< c3> IT-0000021< / c3>
< c4> 12/14/2010 09:56 AM< / c4>
< c5>准备< / c5>
< c6> IT项目< / c6>
< c7>活动< / c7>
< c8> IT< / c8>
< c9> / IT / BIOMED< / c9>
< / report_row>
< report_row>
< c1>< / c1>
< c2> David,Michael John Morning QA Test< / c2>
< c3> IT-0000020< / c3>
< c4> 12/14/2010 08:12 AM< / c4>
< c5>准备< / c5>
< c6> IT项目< / c6>
< c7>活动< / c7>
< c8> IT< / c8>
< c9> / IT / BIOMED< / c9>
< / report_row>
< / report>

 <?xml version =1.0encoding =UTF-8?> 
< report>
< report_row>
< desc>< / desc>
< prname> IT项目消息验证< / prname>
< prnum> IT-0000021< / prnum>
< cdate> 12/14/2010 09:56 AM< / cdate>
< phase>准备< / phase>
< stype> IT Projects< / stype>
< status> Active< / status>
< parent> IT< / parent>
< location> / IT / BIOMED< / location>
< / report_row>
< report_row>
< desc>< / desc>
< prname> David,Michael John Morning QA Test< / prname>
< prnum> IT-0000020< / prnum>
< cdate> 12/14/2010 08:12 AM< / cdate>
< phase>准备< / phase>
< stype> IT Projects< / stype>
< status> Active< / status>
< parent> IT< / parent>
< location> / IT / BIOMED< / location>
< / report_row>
< / report>

我当前的xslt如下所示:

 <?xml version =1.0encoding =ISO-8859-1?> 
< xsl:transform version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transformxmlns:exslt =http://exslt.org/common >
< xsl:output method =xmlindent =yes/>

< xsl:template match =/>
< report>
< xsl:apply-templates select =/ report / report_row/>
< / report>
< / xsl:template>

< xsl:template match =/ report / report_row>
< report_row>
< xsl:apply-templates select =c1/>
< xsl:apply-templates select =c2/>
< xsl:apply-templates select =c3/>
< xsl:apply-templates select =c4/>
< xsl:apply-templates select =c5/>
< xsl:apply-templates select =c6/>
< xsl:apply-templates select =c7/>
< xsl:apply-templates select =c8/>
< xsl:apply-templates select =c9/>
< / report_row>
< / xsl:template>

< xsl:template match =c1>
< xsl:element name ={/ report / report_header / c1}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c2>
< xsl:element name ={/ report / report_header / c2}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c3>
< xsl:element name ={/ report / report_header / c3}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c4>
< xsl:element name ={/ report / report_header / c4}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c5>
< xsl:element name ={/ report / report_header / c5}>< xsl:value-of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c6>
< xsl:element name ={/ report / report_header / c6}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c7>
< xsl:element name ={/ report / report_header / c7}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c8>
< xsl:element name ={/ report / report_header / c8}>< xsl:value -of select =current()/>< / xsl:element&
< / xsl:template>
< xsl:template match =c9>
< xsl:element name ={/ report / report_header / c9}>< xsl:value-of select =current()/>< / xsl:element&
< / xsl:template>

< / xsl:transform>

如果我假设最大列数,并且列标题可以是合法的qnames, / p>

当我超过了我假设的100个限制和列标题包含空格时,它开始失败。



如何创建一个使用通配符的转换,如何从列标题中删除空格和非法字符,使它们成为合法的qnames?



感谢

解决方案

此转换

 code>< xsl:stylesheet version =1.0
xmlns:xsl =http://www.w3.org/1999/XSL/Transform>
< xsl:output omit-xml-declaration =yesindent =yes/>
< xsl:strip-space elements =*/>

< xsl:variable name =vAlphanumselect =
concat('ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz',
'_0123456789'

/>

< xsl:variable name =vRepsselect =
'_____________________________________'/>
< xsl:key name =kColNameByCode
match =report_header / * / text()
use =name(..)/>

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

< xsl:template match =report_row / *>
< xsl:variable name =vNameTextselect =
key('kColNameByCode',name())/>

< xsl:variable name =vElNameselect =
translate($ vNameText,
translate($ vNameText,$ vAlphanum,''),
$ vReps)
/>
< xsl:element name ={$ vElName}>
< xsl:value-of select =。/>
< / xsl:element>
< / xsl:template>
< xsl:template match =report_header/>
< / xsl:stylesheet>

应用于提供的XML文档

 < report> 
< report_header>
< c1> desc< / c1>
< c2>公司名称< / c2>
< c3> pr num< / c3>
< c4> cdate< / c4>
< c5>阶段< / c5>
< c6> stype< / c6>
< c7>状态< / c7>
< c8> parent< / c8>
< c9>位置< / c9>
< / report_header>
< report_row>
< c1>< / c1>
< c2> IT项目消息验证< / c2>
< c3> IT-0000021< / c3>
< c4> 12/14/2010 09:56 AM< / c4>
< c5>准备< / c5>
< c6> IT项目< / c6>
< c7>活动< / c7>
< c8> IT< / c8>
< c9> / IT / BIOMED< / c9>
< / report_row>
< report_row>
< c1>< / c1>
< c2> David,Michael John Morning QA Test< / c2>
< c3> IT-0000020< / c3>
< c4> 12/14/2010 08:12 AM< / c4>
< c5>准备< / c5>
< c6> IT项目< / c6>
< c7>活动< / c7>
< c8> IT< / c8>
< c9> / IT / BIOMED< / c9>
< / report_row>
< / report>

产生想要的正确结果

 < report> 
< report_row>
< desc />
< pr_name> IT项目邮件验证< / pr_name>
< pr_num> IT-0000021< / pr_num>
< cdate> 12/14/2010 09:56 AM< / cdate>
< phase>准备< / phase>
< stype> IT Projects< / stype>
< status> Active< / status>
< parent> IT< / parent>
< location> / IT / BIOMED< / location>
< / report_row>
< report_row>
< desc />
< pr_name> David,Michael John Morning QA Test< / pr_name>
< pr_num> IT-0000020< / pr_num>
< cdate> 12/14/2010 08:12 AM< / cdate>
< phase>准备< / phase>
< stype> IT Projects< / stype>
< status> Active< / status>
< parent> IT< / parent>
< location> / IT / BIOMED< / location>
< / report_row>
< / report>

请注意


$ b b


  1. 转换可将任何数量的不同非字母数字字符的文本成功转换为语法正确的XML名称。

    li>
  2. 使用键获得效率



I need to convert a table of data that comes in xml outputs like the following.C1 column 1 c2 column2 etc

<?xml version="1.0" encoding="UTF-8"?>
<report>
    <report_header>
        <c1>desc</c1>
        <c2>prname</c2>
        <c3>prnum</c3>
        <c4>cdate</c4>
        <c5>phase</c5>
        <c6>stype</c6>
        <c7>status</c7>
        <c8>parent</c8>
        <c9>location</c9>
    </report_header>
    <report_row>
        <c1></c1>
        <c2>IT Project Message Validation</c2>
        <c3>IT-0000021</c3>
        <c4>12/14/2010 09:56 AM</c4>
        <c5>Preparation</c5>
        <c6>IT Projects</c6>
        <c7>Active</c7>
        <c8>IT</c8>
        <c9>/IT/BIOMED</c9>
    </report_row>
    <report_row>
        <c1></c1>
        <c2>David, Michael John Morning QA Test</c2>
        <c3>IT-0000020</c3>
        <c4>12/14/2010 08:12 AM</c4>
        <c5>Preparation</c5>
        <c6>IT Projects</c6>
        <c7>Active</c7>
        <c8>IT</c8>
        <c9>/IT/BIOMED</c9>
    </report_row>
</report>

into

<?xml version="1.0" encoding="UTF-8"?>
<report>
    <report_row>
        <desc></desc>
        <prname>IT Project Message Validation</prname>
        <prnum>IT-0000021</prnum>
        <cdate>12/14/2010 09:56 AM</cdate>
        <phase>Preparation</phase>
        <stype>IT Projects</stype>
        <status>Active</status>
        <parent>IT</parent>
        <location>/IT/BIOMED</location>
    </report_row>
    <report_row>
        <desc></desc>
        <prname>David, Michael John Morning QA Test</prname>
        <prnum>IT-0000020</prnum>
        <cdate>12/14/2010 08:12 AM</cdate>
        <phase>Preparation</phase>
        <stype>IT Projects</stype>
        <status>Active</status>
        <parent>IT</parent>
        <location>/IT/BIOMED</location>
    </report_row>
</report>

my current xslt looks like this

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:exslt="http://exslt.org/common">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
    <report>
        <xsl:apply-templates select="/report/report_row"/>          
    </report>
</xsl:template>

<xsl:template match="/report/report_row">
<report_row>
    <xsl:apply-templates select="c1"/>
    <xsl:apply-templates select="c2"/>
    <xsl:apply-templates select="c3"/>
    <xsl:apply-templates select="c4"/>
    <xsl:apply-templates select="c5"/>
    <xsl:apply-templates select="c6"/>
    <xsl:apply-templates select="c7"/>
    <xsl:apply-templates select="c8"/>
    <xsl:apply-templates select="c9"/>
</report_row>
</xsl:template> 

<xsl:template match="c1">   
    <xsl:element name="{/report/report_header/c1}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>
<xsl:template match="c2">   
    <xsl:element name="{/report/report_header/c2}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template> 
<xsl:template match="c3">   
    <xsl:element name="{/report/report_header/c3}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>
<xsl:template match="c4">   
    <xsl:element name="{/report/report_header/c4}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template> 
<xsl:template match="c5">   
    <xsl:element name="{/report/report_header/c5}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template> 
<xsl:template match="c6">   
    <xsl:element name="{/report/report_header/c6}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>
<xsl:template match="c7">   
    <xsl:element name="{/report/report_header/c7}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>
<xsl:template match="c8">   
    <xsl:element name="{/report/report_header/c8}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>
<xsl:template match="c9">   
    <xsl:element name="{/report/report_header/c9}"><xsl:value-of select="current()"/></xsl:element>
</xsl:template>

</xsl:transform>

My transform works if I assume a maximal number of columns and the column headers can be legal qnames.

It started failing when I got more than the 100 limit I had assumed and column headers with spaces in them.

How do I create a transform that uses wildcards instead and how do I strip spaces and illegal characters from the column headers to make them legal qnames?

Thanks

解决方案

This transformation:

<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:variable name="vAlphanum" select=
  "concat('ABCDEFGHIJKLMNOPQRSTUVWXYZ',
          'abcdefghijklmnopqrstuvwxyz',
          '_0123456789'
         )
  "/>

 <xsl:variable name="vReps" select=
  "'_____________________________________'"/>
 <xsl:key name="kColNameByCode"
       match="report_header/*/text()"
       use="name(..)"/>

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

 <xsl:template match="report_row/*">
  <xsl:variable name="vNameText" select=
   "key('kColNameByCode', name())"/>

  <xsl:variable name="vElName" select=
  "translate($vNameText,
             translate($vNameText,$vAlphanum,''),
             $vReps)
  "/>
  <xsl:element name="{$vElName}">
    <xsl:value-of select="."/>
  </xsl:element>
 </xsl:template>
 <xsl:template match="report_header"/>
</xsl:stylesheet>

when applied to the provided XML document:

<report>
    <report_header>
        <c1>desc</c1>
        <c2>pr name</c2>
        <c3>pr num</c3>
        <c4>cdate</c4>
        <c5>phase</c5>
        <c6>stype</c6>
        <c7>status</c7>
        <c8>parent</c8>
        <c9>location</c9>
    </report_header>
    <report_row>
        <c1></c1>
        <c2>IT Project Message Validation</c2>
        <c3>IT-0000021</c3>
        <c4>12/14/2010 09:56 AM</c4>
        <c5>Preparation</c5>
        <c6>IT Projects</c6>
        <c7>Active</c7>
        <c8>IT</c8>
        <c9>/IT/BIOMED</c9>
    </report_row>
    <report_row>
        <c1></c1>
        <c2>David, Michael John Morning QA Test</c2>
        <c3>IT-0000020</c3>
        <c4>12/14/2010 08:12 AM</c4>
        <c5>Preparation</c5>
        <c6>IT Projects</c6>
        <c7>Active</c7>
        <c8>IT</c8>
        <c9>/IT/BIOMED</c9>
    </report_row>
</report>

produces the wanted, correct result:

<report>
   <report_row>
      <desc/>
      <pr_name>IT Project Message Validation</pr_name>
      <pr_num>IT-0000021</pr_num>
      <cdate>12/14/2010 09:56 AM</cdate>
      <phase>Preparation</phase>
      <stype>IT Projects</stype>
      <status>Active</status>
      <parent>IT</parent>
      <location>/IT/BIOMED</location>
   </report_row>
   <report_row>
      <desc/>
      <pr_name>David, Michael John Morning QA Test</pr_name>
      <pr_num>IT-0000020</pr_num>
      <cdate>12/14/2010 08:12 AM</cdate>
      <phase>Preparation</phase>
      <stype>IT Projects</stype>
      <status>Active</status>
      <parent>IT</parent>
      <location>/IT/BIOMED</location>
   </report_row>
</report>

Do note:

  1. The transformation successfully converts any text with any number of different non-alphanumeric characters to a syntactically-correct XML name.

  2. Efficiency is achieved using keys.

这篇关于XSLT转换从元素创建新的qnames的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 23:36