使用 XSLT 从两个合并的 XML 文件中提取数据 [英] Extract data with XSLT from two combined XML files
问题描述
我用 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屋!