我有两个XML文档。一个(我们称之为xml1)列出了一系列“ w”元素,每个元素都有一个“ orig”属性。另一个文档(xml2)列出了一系列相关的“ w”元素,但是具有不同的属性(“ norm”)。我想合并两个文档,以便只拥有一系列具有所有属性(“ orig”和“ norm”)的元素。
这听起来很容易,但是我无法完全使代码正常工作,也无法使代码选择属性'norm'的单个值,而不是所有可用值。
我尝试使用命令
从xml2中选择属性的值<xsl:value-of select="document('xml2.xml')//@norm"/>
但是所有要做的就是选择xml2中所有'norm'属性的值。
我还尝试为两个文档中的每个元素赋予唯一的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>
如果可以,请帮助我。谢谢。
答案 0 :(得分:0)
最好使用 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>
答案 1 :(得分:-1)
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="imp" select="document('Stanza1.xml')"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="l">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="w">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:copy-of select="$imp/text/seg/l/w[@xml:id = current()/@xml:id]/@norm"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
You may use like this