XSLT 转换从元素创建新的 qname [英] XSLT conversion creating new qnames from elements
问题描述
我需要转换 xml 输出中的数据表,如下所示.C1 列 1 c2 列 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>
进入
<?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>
我现在的 xslt 是这样的
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>
如果我假设最大数量的列并且列标题可以是合法的 qnames,我的转换就可以工作.
My transform works if I assume a maximal number of columns and the column headers can be legal qnames.
当我得到超过我假设的 100 个限制并且列标题中有空格时,它开始失败.
It started failing when I got more than the 100 limit I had assumed and column headers with spaces in them.
如何创建使用通配符的转换以及如何从列标题中去除空格和非法字符以使其成为合法的 qname?
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?
谢谢
推荐答案
这个转变:
<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>
应用于提供的 XML 文档时:
<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>
产生想要的正确结果:
<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>
请注意:
转换成功地将具有任意数量的不同非字母数字字符的任何文本转换为语法正确的 XML 名称.
The transformation successfully converts any text with any number of different non-alphanumeric characters to a syntactically-correct XML name.
效率是通过按键实现的.
这篇关于XSLT 转换从元素创建新的 qname的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!