XSLT - 使用 Xsl 将 Xml 转换为 Xml

XSLT - Transform Xml to Xml using Xsl

我有两个 xml 文件,我想使用第一个和第二个 Xml 文件创建一个新的 XMl 文件。我想使用第二个文件节点 <entite_nom > 修改 <w> 节点。

第一个文件: [编辑]

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="transformation.xsl" ?>
<TEI xmlns="http://www.tei-c.org/ns/1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.tei-c.org/ns/1.0 file:document.xsd">

    <text>
        <body>
            <p>
                <s>
                        <name>
                            <w type="NAM">Cussac</w>
                        </name>
                        <w lemma="en" type="PRP">en</w>
                        <name>
                            <w type="NAM">Haute-Vienne</w>
                        </name>
                </s>
                <s>
                    <phr type="verb_phrase" subtype="motion" function="reach">
                        <w lemma="prendre" type="VER:pres">prenez</w>
                        <w lemma="le" type="DET:ART">la</w>
                        <w lemma="route" type="NOM">route</w>
                        <offset type="temporal" subtype="final">
                            <w lemma="pour" type="PRP">pour</w>
                            <w lemma="finir" type="VER:infi">finir</w>
                        </offset>
                        <w lemma="de" type="PRP">d'</w>
                        <w lemma="arriver" type="VER:infi">arriver</w>
                        <offset type="inclusion">
                            <w lemma="sur" type="PRP">sur</w>
                        </offset>
                        <name>
                            <w type="NAM">Cussac</w>
                        </name>
                    </phr>
                    <pc force="strong">.</pc>
                </s>
                <s>
                    <w lemma="il" type="PRO:PER">Il</w>
                    <phr type="verb_phrase" subtype="position">
                        <w lemma="revenir" type="VER:pres">revient</w>
                        <w lemma="tranquillement" type="ADV">tranquillement</w>
                        <offset type="inclusion">
                            <w lemma="sur" type="PRP">sur</w>
                        </offset>
                        <name>
                            <w type="NAM">Cussac</w>
                        </name>
                    </phr>
                    <pc force="strong">.</pc>
                </s>

我需要选择 Id<entite_nom> 节点的值并添加到第一个 XMl 的 <w> 节点 第二个文件($doc2):

<?xml version="1.0" encoding="UTF-8"?>
<geolocalisation  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:noNamespaceSchemaLocation="localisation-2.xsd">
   <entite_nom id="en.0" lng="0.8519611512411495" lat="45.7055740420633" alt="349.0322265625">Cussac</entite_nom>
   <entite_nom id="en.1" lng="0.859333" lat="45.712939" alt="280.5089111328125">Monnerie</entite_nom>
   <entite_nom id="en.2" lng="0.857138" lat="45.687754" alt="376.1028137207031">Liades</entite_nom>
   <entite_nom id="en.3" lng="0.8256439978387133" lat="45.67243279742165" alt="415.4050903320312">Boubon</entite_nom>
   <entite_nom id="en.4" lng="0.8219117961938217" lat="45.67606269511061" alt="420.0135498046875">Villajou</entite_nom>
   <entite_nom id="en.5" lng="0.8150905847864954" lat="45.68782102152895" alt="380.9435729980469">Puymoroux</entite_nom>
   <entite_nom id="en.6" lng="0.8519611512411495" lat="45.7055740420633" alt="349.0322265625">Cussac</entite_nom>
   <entite_nom id="en.7" lng="0.8519611512411495" lat="45.7055740420633" alt="349.0322265625">Cussac</entite_nom>   
</geolocalisation>

我想要得到的结果:

<placeName id="en.0" 
         ref="file:fr_Cussac_coord_entites.xml">
         <name>
          <w type="NPr">Cussac</w>
         </name>
</placeName>

到目前为止我尝试了什么,但我无法获得 id 值:

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:variable name="path">file:fr_Cussac-cood-entites.xml</xsl:variable>
    <xsl:key name="ref" match="entite_nom" use="."/>

    <xsl:param name="doc2" select="document('fr_Cussac-coord-entites.xml')/geolocalisation"/>  

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

    <xsl:template match="tei:name[key('ref', tei:w[@type], $doc2)]">
        <placeName id="{key('ref', w[@type], $doc2)/@id}" ref="{$path}">
            <xsl:copy-of select="."/>
        </placeName>   
</xsl:template>
</xsl:stylesheet>

我得到的是空 id,我无法获取 id 值:

<placeName id="" ref="file:fr_Cussac-cood-entites.xml">
            <name>
               <w type="NAM">Cussac</w>
            </name>
</placeName>

看来钥匙的工作:

<?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"
    xmlns:tei="http://www.tei-c.org/ns/1.0"
    xmlns="http://www.tei-c.org/ns/1.0"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:key name="ref" match="entite_nom" use="."/>

  <xsl:param name="doc2" select="doc('file2.xml')"/>

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

  <xsl:template match="tei:name[key('ref', tei:w[@type], $doc2)]">
     <placeName id="{key('ref', tei:w[@type], $doc2)/@id}">
         <xsl:copy-of select="."/>
     </placeName> 
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/a9GPfD/1

使用带有第三个参数的 key 函数来提供上下文文档或子树仅限于 XSLT 2 及更高版本。

如果您希望有多个元素具有相同的词,并希望根据文档中的位置找到不同的 ID,那么

  <xsl:template match="tei:name[key('ref', tei:w[@type], $doc2)]">
     <xsl:variable name="word" select="tei:w[@type]"/>
     <xsl:variable name="pos" as="xs:integer">
         <xsl:number level="any" count="tei:name[tei:w[@type] = $word]"/>
     </xsl:variable>
     <placeName id="{key('ref', tei:w[@type], $doc2)[$pos]/@id}">
         <xsl:copy-of select="."/>
     </placeName> 
  </xsl:template>

https://xsltfiddle.liberty-development.net/a9GPfD/2

在XSLT 3中可能还可以使用组合键或累加器来区分位置,我目前不确定哪种方法更好,以上主要是尝试调整之前的建议以适合您改变了,更复杂的要求。