如何在 xslt 中应用引用值的模板?

How do you apply template referencing a value in xslt?

这是我刚刚编造的一个例子(所以不要以错别字或缩进来评判我):-

<?xml version="1.0" encoding="UTF-8"?>
<company id="c123" name="comp 1">

 <buildings>

  <building id="b1" name="bld1">

   <department ref="d1"/>

   <department ref="d3"/>

</building>

 </buildings>

 <departments>

  <department id="d1" name="IT">

   <desc>Lorem ipsum</desc>

  <cto>Mr. X</cto>

  </department>

  <department id="d2" name="HR">

    <desc>Lorem ipsum</desc>

    <coo>Mr. Y</coo>

    </department>

<department id="d3" name="Finance">

    <desc>Lorem ipsum</desc>

    <cfo>Mr. Z</cfo>

    </department>

 </departments>

</company>

所以我想获得类似于每栋建筑的信息,其中包含它所引用的部门的所有详细信息。

我尝试传递参数并在部门模板中使用它,但这没有用。我有一种感觉,我的 与建筑物本身内部的 "department" 相匹配,我的 xpath 做错了,因为我是新手。我的想法是尝试上升到父节点的级别,然后使用 match="../../departments/department[@ref]" 之类的东西,但这也不起作用。 有什么建议吗?

编辑: 预期输出:

<company id="c123" name="comp 1">

 <building id="b1" name="bld1">

  <department id="d1" name="IT" desc="Lorem ipsum" cto="Mr. X"/>

  <department id="d3" name="Finance" desc="Lorem ipsum" cfo="Mr. Z" />

 </building>
</company>

我建议对您的问题做出以下回答:

输入:

::::::::::::::
companies.xml
::::::::::::::
<?xml version="1.0" encoding="UTF-8"?>
<company id="c123" name="comp 1">
 <buildings>
  <building id="b1" name="bld1">
   <department ref="d1"/>
   <department ref="d3"/>
</building>
 </buildings>
 <departments>
  <department id="d1" name="IT">
   <desc>Lorem ipsum</desc>
  <cto>Mr. X</cto>
  </department>
  <department id="d2" name="HR">
    <desc>Lorem ipsum</desc>
    <coo>Mr. Y</coo>
    </department>
<department id="d3" name="Finance">
    <desc>Lorem ipsum</desc>
    <cfo>Mr. Z</cfo>
    </department>
 </departments>
</company>

样式表文件:

::::::::::::::
companies.xsl
::::::::::::::
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<!-- Identity template : copy all text nodes, elements and attributes -->   
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<!-- When matching department: do nothing -->
<xsl:template match="departments" /> 
<xsl:template match="/departments/department" /> 


<xsl:template match="building">
   <!-- create the node building with attributes -->
   <building id="{./@id}" name="{./@name}">
    <!-- loop on each department and extract the relevant data -->
    <xsl:for-each select="./department">
      <xsl:variable name="refvar" select="./@ref"/>
      <department id="{./@ref}" name="{//department[@id=$refvar]/@name}" desc="{//department[@id=$refvar]/desc}">
       <xsl:attribute name="{name(//department[@id=$refvar]/*[position() = 2])}">
        <xsl:value-of select="//department[@id=$refvar]/*[position() = 2]"/>
       </xsl:attribute>
      </department>


    </xsl:for-each>
   </building>
</xsl:template>

</xsl:stylesheet>

输出:

$ xsltproc companies.xsl companies.xml | xmllint --format -
<?xml version="1.0" encoding="utf-8"?>
<company id="c123" name="comp 1">
  <buildings>
    <building id="b1" name="bld1">
      <department id="d1" name="IT" desc="Lorem ipsum" cto="Mr. X"/>
      <department id="d3" name="Finance" desc="Lorem ipsum" cfo="Mr. Z"/>
    </building>
  </buildings>
</company>