使用 XSLT 从两个合并的 XML 文件中提取数据 [英] Extract data with XSLT from two combined XML files

查看:41
本文介绍了使用 XSLT 从两个合并的 XML 文件中提取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 XML 表示了两个数据库表.

I have a representation of two DB tables in XML.

记录.xml

 <?xml version="1.0" encoding="UTF-8"?>
        <?xml-stylesheet type="text/xsl" href="transform.xsl"?>        
            <records>
            <record>
             <ID>20345</ID>
             <name>John Doe</name>
             <address>23 Green Hill, NY</address>
            </record>
            ...
            <record>
             <ID>67357</ID>
             <name>Simon Lee</name>
             <address>23 South Oates Street, Dothan</address>
            </record>
            </records>

工作.xml

<?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="transform.xsl"?>
    
        <employees>
        <employee>
        <ID>20345</ID>
        <position>General Manager</position>
        <level>0</level>
        </employee>
        ...
        <employee>
        <ID>67357</ID>
        <position>Senior Officer</position>
        <level>1</level>
        </employee>
        </employees>

我的 XSLT 文件 transform.xsl 是:

My XSLT file transform.xsl is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:xs="http://www.w3.org/2001/XMLSchema"         
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output media-type="xml" indent="yes" method="xml" encoding="UTF-8"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="/records/record">   
            <record>            
                <ID><xsl:value-of select="ID"/></ID>
                <name><xsl:value-of select="name"/></name>
                <address><xsl:value-of select="address"/></address>
                <position><xsl:value-of select="document(work.xml)/employees/employee/position"/></position>
                <level><xsl:value-of select="document(work.xml)/employees/employee/level"/></level>     
            </record>       
        </xsl:template>
    </xsl:stylesheet>

我正在尝试根据表单中的 ID 合并每个员工的数据:

I am trying to merge the data for each employee based on ID in the form:

ID> 20345
name> John Doe 
address> 23 Green Hill, NY
position> General Manager
level> 0
...
ID> 67357
name> Simon Lee
address> 23 South Oates Street, Dothan
position> Senior Officer
level> 1

我尝试使用带有参数 $position 和 $level 的模板,但我不确定要使用什么 XQuery.

I tried to use a template with parameters $position and $level but I am not sure what XQuery to use.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" />
<xsl:output media-type="xml" indent="yes" method="xml" encoding="UTF-8"/>

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

<xsl:param name="work" select="work.xml" />
<xsl:param name="merged" select="document($work)" />
<xsl:variable name="ID" select="$merged/employees/employee/ID" />
<xsl:variable name="position" select="$merged/employees/employee/position" />
<xsl:variable name="level" select="$merged/employees/employee/level" />


<xsl:key name="IDkey" match="$ID" use="ID"/>
  
  <xsl:template match="/records/record"/>
  <xsl:template match="employees/employee">
  <xsl:value-of select="key('IDkey',document(work.xml)/employees/employee/ID])"/>
  <xsl:apply-templates/>  
  </xsl:template>


<xsl:template match="/records/record">   
        <record>            
            <ID><xsl:value-of select="ID"/></ID>
            <name><xsl:value-of select="name"/></name>
            <address><xsl:value-of select="address"/></address> 
            <position><xsl:value-of select="position"/></position>
            <level><xsl:value-of select="level"/></level>               
        </record>       
    </xsl:template>
</xsl:stylesheet>

我真的很感激一些帮助..

I would really appreciate some help..

推荐答案

最简单的基于键的交叉引用是

Simplest key based cross-reference would be

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="work">
<employees>
        <employee>
        <ID>20345</ID>
        <position>General Manager</position>
        <level>0</level>
        </employee>
        ...
        <employee>
        <ID>67357</ID>
        <position>Senior Officer</position>
        <level>1</level>
        </employee>
        </employees>      
  </xsl:param>
  
  <xsl:key name="id" match="employee" use="ID"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="record[key('id', ID, $work)]">
      <xsl:copy>
          <xsl:apply-templates select="node(), key('id', ID, $work)!(position, level)"/>
      </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

其他数据在上面内嵌(并在 https://xsltfiddle.liberty-development.net 在线/nb9PtEb) 用于示例的紧凑性和自包含性,但当然使用 的工作方式相同.

The other data is inline above (and online at https://xsltfiddle.liberty-development.net/nb9PtEb) for compactness and self-containedness of the example but of course using <xsl:param name="work" select="doc('work.xml')"/> would work the same way.

这篇关于使用 XSLT 从两个合并的 XML 文件中提取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆