xml - 如何使用 XSLT 从另一个 XML 文档提供属性值?
问题描述
我有两个 XML 文档。一个(我们称之为 xml1)列出了一系列“w”元素,每个元素都有一个“orig”属性。另一个文档 (xml2) 列出了一系列相关的 'w' 元素,但具有不同的属性 ('norm')。我想合并这两个文档,这样我就只有一系列具有所有属性(“orig”和“norm”)的元素。
这听起来很简单,但我无法让代码正常工作,我无法让代码选择属性“规范”的单个值,而不是所有可用值。
我尝试使用命令从 xml2 中选择属性的值
<xsl:value-of select="document('xml2.xml')//@norm"/>
但这所做的只是选择 xml2 中所有“规范”属性的值。
我还尝试给两个文档中的每个元素一个唯一的 xml:id 属性,以便它们可以匹配,但是任何时候我使用条件语句来匹配它们,我都会得到相同的结果。
如果我使用“for each”命令,则不会选择任何元素。
这是 xml1 的示例:
<text>
<seg type="stanza" n="1">
<l n="1">
<w xml:id="1" orig="Haile"/>
<w xml:id="2" orig=","/>
<w xml:id="3" orig="sterne"/>
<w xml:id="4" orig="superne"/>
<w xml:id="5" orig="!"/>
</l>
</seg>
</text>
这是 xml2 的示例:
<text>
<seg type="stanza" n="1">
<l n="1">
<w xml:id="1" norm="Hail"/>
<w xml:id="2" norm=","/>
<w xml:id="3" norm="star"/>
<w xml:id="4" norm="supernal"/>
<w xml:id="5" norm="!"/>
</l>
</seg>
</text>
我想制作这个:
<text>
<seg type="stanza" n="1">
<l n="1">
<w xml:id="1" orig="Haile" norm="Hail"/>
<w xml:id="2" orig="," norm=","/>
<w xml:id="3" orig="sterne" norm="star"/>
<w xml:id="4" orig="superne" norm="supernal"/>
<w xml:id="5" orig="!" norm="!"/>
</l>
</seg>
</text>
到目前为止,我的 xslt 文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.tei-c.org/ns/1.0"
xmlns="http://www.tei-c.org/ns/1.0"
version="2.0">
<xsl:output method="xml" indent="no"/>
<!-- select the entirety of the document -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- combine attributes from separate files -->
<xsl:template match="//w">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="norm">
<xsl:value-of select="document('xml2.xml')//@norm"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果可以的话,请帮助我。谢谢。
解决方案
查找最好使用key处理。尝试(未经测试):
XSLT 2.0
<xsl:stylesheet version="2.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:key name="norm" match="w" use="@xml:id" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="w">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="key('norm', @xml:id, document('xml2.xml'))/@norm"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- .htaccess - htaccess 强制 ssl/https 和非 www,同时允许框架路由到 /public
- javascript - 电子生成器无法正确安装
- haskell - 为什么我不能在不同的数据类型之间重用相同的值构造函数?
- android - ViewModel、Room、LiveData、RecyclerView 过滤数据
- python - Python Pyautogui 等待系统响应
- android - 使用自定义响应进行改造 2 处理套接字超时异常
- c++ - C++/Qt - 析构函数中的异常 -> 中止已被调用
- python - 在scrapy上拆分并保存文本字符串
- python - python - 使用pickle.load()时没有名为dill的模块
- c# - 如何在 C# 中将日期和时间分别解析为 DateTime?