所以,我正在尝试将一些XML转换为易于转换为数据库的格式。这就是它的样子:
<?xml version="1.0" encoding="UTF-8"?>
<detail type="Courses Taken" gm_recid="FNBYHVW(,7()E)S" >
<properties>
<property name="reference" >
<property_string>M2</property_string>
</property>
<property name="Month YYYY" db_name="TITLE" >
<property_string></property_string>
</property>
<property name="City, State" db_name="LINKACCT" >
<property_string></property_string>
</property>
</properties>
</detail>
我更喜欢看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<courses_taken>
<gm_recid>FNBYHVW(,7()E)S</gm_recid>
<reference>M2</reference>
<date></date>
<location></location>
</courses_taken>
我对XSL不太熟悉,所以我不知道从哪里开始。有人能指出我正确的方向吗?
答案 0 :(得分:2)
完整的XSLT转换:
<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="vUpper" select=
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="vLower" select=
"'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vDigits" select=
"'0123456789'"/>
<xsl:variable name="vAlphaNum" select=
"concat($vUpper, $vLower, $vDigits, '_')"/>
<xsl:template match="detail">
<xsl:element name=
"{translate(@type,
translate(@type, $vAlphaNum, ''),
'______________________________'
)}">
<xsl:apply-templates select=
"@*[not(name()='type')]|*"/>
</xsl:element>
</xsl:template>
<xsl:template match="detail/@*">
<xsl:element name=
"{translate(name(),
translate(name(), $vAlphaNum, ''),
'______________________________'
)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="property[@name='reference']">
<reference>
<xsl:value-of select="."/>
</reference>
</xsl:template>
<xsl:template match="property[@name='Month YYYY']">
<date>
<xsl:value-of select="."/>
</date>
</xsl:template>
<xsl:template match="property[@name='City, State']">
<location>
<xsl:value-of select="."/>
</location>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<detail type="Courses Taken" gm_recid="FNBYHVW(,7()E)S" >
<properties>
<property name="reference" >
<property_string>M2</property_string>
</property>
<property name="Month YYYY" db_name="TITLE" >
<property_string></property_string>
</property>
<property name="City, State" db_name="LINKACCT" >
<property_string></property_string>
</property>
</properties>
</detail>
生成想要的正确结果:
<Courses_Taken>
<gm_recid>FNBYHVW(,7()E)S</gm_recid>
<reference>M2</reference>
<date/>
<location/>
</Courses_Taken>
解释:使用@Michael Kay首先提出的双翻译方法的变体:
如果我们有一个字符串$s
和一串只允许的字符$valid
,我们希望从$s
获得另一个字符串$s2
,其中只包含有效字符$s
(按原始顺序),可以通过评估以下XPath表达式来实现:
translate($s, translate($s, $valid, ''), '')
在这种特殊情况下,我们不想删除无效字符,而是用 "_"
替换每个字符。
我们假设候选名称不会超过30 的长度并使用固定长度的替换字符串(当然这可以根据需要制作):
translate($s,
translate($s, $valid, ''),
'______________________________')
答案 1 :(得分:1)
这应该让你开始:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template name="replace">
<xsl:param name="ptext"/>
<xsl:param name="ppattern"/>
<xsl:param name="preplacement"/>
<xsl:choose>
<xsl:when test="not(contains($ptext, $ppattern))">
<xsl:value-of select="$ptext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($ptext, $ppattern)"/>
<xsl:value-of select="$preplacement"/>
<xsl:call-template name="replace">
<xsl:with-param name="ptext"
select="substring-after($ptext, $ppattern)"/>
<xsl:with-param name="ppattern" select="$ppattern"/>
<xsl:with-param name="preplacement" select="$preplacement"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="detail">
<xsl:variable name="elemName">
<xsl:call-template name="replace">
<xsl:with-param name="ppattern" select="' '"/>
<xsl:with-param name="ptext" select="@type"/>
<xsl:with-param name="preplacement" select="'_'"/>
</xsl:call-template>
</xsl:variable>
<xsl:element name="{$elemName}">
<gm_recid>
<xsl:value-of select="@gm_recid"/>
</gm_recid>
<xsl:apply-templates select="properties"/>
</xsl:element>
</xsl:template>
<xsl:template match="properties">
<xsl:for-each select="property">
<!--Do something...-->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
您的属性包含空格和/或其他无效元素字符,因此您可能必须决定如何单独处理。
同时替换此处的模板: