简体   繁体   English

使用XSLT从一个XML到另一个XML的一对一映射

[英]One to One mapping from One XML to another XML using XSLT

I have two XSDs. 我有两个XSD。 The sample XML for these two XSDs are as follows 这两个XSD的示例XML如下所示

**XML -1**                            **XML -2**

<root>                                <parent>
  <e1 />                                <a1 />
  <e2 />                                <a2 />
    .                                     .
    .                                     .
    .                                     .
  <e600 />                              <a600/>
</root>                               </parent>

I need to write an XSLT for data transformation. 我需要编写XSLT进行数据转换。 The value of element " e(i) " needs to be mapped to " a(i) " 元素“ e(i) ”的值需要映射到“ a(i)

Now I can write an XSLT like below 现在我可以编写如下的XSLT

<parent>
  <a1>
    <xsl:value-of select = "/root/e1/text()"/>
  </a1>
  <a2>
    <xsl:value-of select = "/root/e2/text()"/>
  </a2>
    .
    .
  <a600>
    <xsl:value-of select = "/root/e600/text()"/>
  </a600>
</parent>

But this way it is very tedious. 但是这样很繁琐。 Anyone can help or suggest whether to write an XSLT for this purpose in a small way within one template using XSLT 1.0. 任何人都可以使用XSLT 1.0在一个模板内以较小的方式帮助或建议是否为此目的编写XSLT。

How about: 怎么样:

XSLT 1.0 XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/root">
    <parent>
        <xsl:apply-templates/>
    </parent>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="a{substring-after(name(), 'e')}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Added: 添加:

In actual XSD, the elements' name are not like this. 在实际的XSD中,元素的名称不是这样。 These 600 elements are having some different names, no number, nothin common 这600个元素具有不同的名称,没有数字,没有共同之处

If there is no way to calculate the target element's name from the source, then you must resort to some sort of a lookup . 如果无法从源中计算目标元素的名称,则必须诉诸某种lookup This could be in the form of a template for each element, or xsl:choose or selecting from an array. 这可以是每个元素的模板的形式,或者xsl:choose或从数组中选择。

For example, you could do: 例如,您可以这样做:

<xsl:template match="*">
    <xsl:variable name="name">
        <xsl:choose>
            <xsl:when test="name()='e1'">a1</xsl:when>
            <xsl:when test="name()='e2'">a2</xsl:when>
            <xsl:when test="name()='e600'">a600</xsl:when>
        </xsl:choose>
    </xsl:variable>
    <xsl:element name="{$name}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

Or perhaps a bit more efficiently: 也许更有效率:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="nm" match="name" use="@source" />

<my:name-map>
    <name source="e1">a1</name>
    <name source="e2">a2</name>
    <name source="e600">a600</name>
</my:name-map>

<xsl:template match="/root">
    <parent>
        <xsl:apply-templates/>
    </parent>
</xsl:template>

<xsl:template match="*">
    <xsl:variable name="source-name" select="name()" />
    <xsl:variable name="target-name">
        <xsl:for-each select="document('')">
            <xsl:value-of select="key('nm', $source-name)"/>            
        </xsl:for-each>
    </xsl:variable>
    <xsl:element name="{$target-name}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM