XSL 从两个 xml 文件匹配和复制元素名称

发布于 2024-10-26 19:28:43 字数 3693 浏览 1 评论 0原文

我使用以下 xsl 将两个源 xml 文档中的值与名称进行匹配(感谢本网站上其他人的大量帮助)。所以这个:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>    
 <xsl:key name="kPhysByName" match="KB_XMod_Modules" use="Physician"/>              
 <xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

 <xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
  <xsl:variable name="vCur" select="."/>
  <xsl:for-each select="document('profiles.xml')">
   <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
   <xsl:copy>
    <items>
     <item>
      <label><xsl:value-of select="$vMod/Physician"/></label>
      <value><xsl:value-of select="$vMod/XModID"/></value>
     </item>
    </items>
   </xsl:copy>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

...匹配这些:

<?xml version="1.0" encoding="utf-8"?>
<instance>
  <record>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
  </record>
    <record>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
  </record>
</instance>

<?xml version="1.0" encoding="utf-8"?>
<root>
    <KB_XMod_Modules>
        <Physician>Dr Phibes</Physician>
        <XModID>60</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr X</Physician>
        <XModID>61</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr Chivago</Physician>
        <XModID>62</XModID>
    </KB_XMod_Modules>
</root>

...产生这个:

 <instance>
  <record>
    <items>
      <item>
        <label>Dr Phibes</label>
        <value>60</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr X</label>
        <value>61</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr Chivago</label>
        <value>62</value>
      </item>
    </items>
  </record>
  <record>
    <items>
      <item>
        <label>Dr Phibes</label>
        <value>60</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr X</label>
        <value>61</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr Chivago</label>
        <value>62</value>
      </item>
    </items>
  </record>
</instance>

但是在这个例子中父 < ;InfBy3> 标签丢失。我正在努力寻找一种方法来复制这些元素,同时保持正确的名称,这样我就可以:

<InfBy1>
  <items>
    <item>
      <label>Dr Phibes</label>
      <value>60</value>
    </item>
  </items>
</InfBy1>
<InfBy2>
  <items>
    <item>
      <label>Dr X</label>
      <value>61</value>
    </item>
  </items>
</InfBy2>       
...etc

感谢您的浏览...

I'm matching values to names from two source xml documents with the following xsl (thanks to plenty of help from others on this site). So this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>    
 <xsl:key name="kPhysByName" match="KB_XMod_Modules" use="Physician"/>              
 <xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

 <xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
  <xsl:variable name="vCur" select="."/>
  <xsl:for-each select="document('profiles.xml')">
   <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
   <xsl:copy>
    <items>
     <item>
      <label><xsl:value-of select="$vMod/Physician"/></label>
      <value><xsl:value-of select="$vMod/XModID"/></value>
     </item>
    </items>
   </xsl:copy>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

...matches these:

<?xml version="1.0" encoding="utf-8"?>
<instance>
  <record>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
  </record>
    <record>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
  </record>
</instance>

<?xml version="1.0" encoding="utf-8"?>
<root>
    <KB_XMod_Modules>
        <Physician>Dr Phibes</Physician>
        <XModID>60</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr X</Physician>
        <XModID>61</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr Chivago</Physician>
        <XModID>62</XModID>
    </KB_XMod_Modules>
</root>

...to produce this:

 <instance>
  <record>
    <items>
      <item>
        <label>Dr Phibes</label>
        <value>60</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr X</label>
        <value>61</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr Chivago</label>
        <value>62</value>
      </item>
    </items>
  </record>
  <record>
    <items>
      <item>
        <label>Dr Phibes</label>
        <value>60</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr X</label>
        <value>61</value>
      </item>
    </items>
    <items>
      <item>
        <label>Dr Chivago</label>
        <value>62</value>
      </item>
    </items>
  </record>
</instance>

However in this example the parent <InfBy1>, <InfBy2> and <InfBy3>tags are missing. I'm struggling to find a way of copying these elements over while maintaining the correct name so that I have:

<InfBy1>
  <items>
    <item>
      <label>Dr Phibes</label>
      <value>60</value>
    </item>
  </items>
</InfBy1>
<InfBy2>
  <items>
    <item>
      <label>Dr X</label>
      <value>61</value>
    </item>
  </items>
</InfBy2>       
...etc

Thanks for looking...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

银河中√捞星星 2024-11-02 19:28:43

首先,xsl:copy 指令在该上下文(具有 'profiles.xml' URI 的文档的根节点)中毫无用处。

这导致了实际的答案:使用 xsl:copy 指令,其中上下文是匹配的元素。

<xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
 <xsl:variable name="vCur" select="."/>
 <xsl:copy>     
  <xsl:for-each select="document('profiles.xml')">
   <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
   <items>
    <item>
     <label>
      <xsl:value-of select="$vMod/Physician"/>
     </label>
     <value>
      <xsl:value-of select="$vMod/XModID"/>
     </value>
    </item>
   </items>
  </xsl:for-each>
 </xsl:copy>   
</xsl:template> 

First, the xsl:copy instruction is useless in that context (root node of document with 'profiles.xml' URI).

That leads to the actual answer: use xsl:copy instruction where the context is the matched element.

<xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
 <xsl:variable name="vCur" select="."/>
 <xsl:copy>     
  <xsl:for-each select="document('profiles.xml')">
   <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
   <items>
    <item>
     <label>
      <xsl:value-of select="$vMod/Physician"/>
     </label>
     <value>
      <xsl:value-of select="$vMod/XModID"/>
     </value>
    </item>
   </items>
  </xsl:for-each>
 </xsl:copy>   
</xsl:template> 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文