Xml XSLT:将属性从一个节点移动到现有节点[更新日期23/7/14]

Xml XSLT:将属性从一个节点移动到现有节点[更新日期23/7/14],xml,xslt,Xml,Xslt,我在这方面已经做了一段时间了——XSLT基本上可以正常工作,删除了不需要的节点和属性,但其中有一部分让我感到困惑 我的想法是,我有3个元素,每个元素有1个属性,我想将属性从第二个和第三个元素移动到第一个元素(并删除第二个和第三个元素) [片段1]来自: <info> <id name="Tim"/> <address addr="1 Witchwood Close"/> <phone num="01234 567 891"/>

我在这方面已经做了一段时间了——XSLT基本上可以正常工作,删除了不需要的节点和属性,但其中有一部分让我感到困惑

我的想法是,我有3个元素,每个元素有1个属性,我想将属性从第二个和第三个元素移动到第一个元素(并删除第二个和第三个元素)

[片段1]来自:

<info>
    <id name="Tim"/>
    <address addr="1 Witchwood Close"/>
    <phone num="01234 567 891"/>
</info>
我得到了同样的结果。那么为什么下面包含“/”而不是“|”的同级语句不进行任何转换呢?很明显我遗漏了一些简单的东西

编辑2(inc解决方案)

我想我已经整理好了。意识到我需要对XPath进行升级(到目前为止,这可能是非常明显的!),我并不真的知道wtf正在进行中,我提出了以下代码片段:

<xsl:template match="id">
  <xsl:copy>
    <xsl:apply-templates select="@name | following-sibling::*//@addr"/>
    <xsl:apply-templates select="@name | @addr | following-sibling::*//@num"/>
  </xsl:copy>
</xsl:template>

产生:

<info>
  <id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
</info>

这正是我想要的!我认为这可能不是最优雅的做事方式,但它似乎完成了工作……只有一个小例外。 有时,输出将是(没有明显的原因说明为什么是这一个而不是另一个):


尽管在复制之后删除了节点。这不是一个大问题,因为SQL XML导入设置为仅导入由“id”标识的行上的字段,因此忽略“address”行

我已经将Eero的答案标记为“接受”,因为这给了我最终解决问题的方向,不管我的代码实际上有多难看。欢迎评论如何使它不那么混乱


谢谢大家!

像这样一个简单的样式表应该可以做到:

样式表


能否显示xslt中创建
id
元素的部分?您好。包含所有数据的“完整”xml文件是从另一个工具输出的,并且包含的信息远远超过需要的信息-因此,我使用xslt缩减了xml,这是最后一步。我不确定这是你想要的。嗨,有很多方法可以做你想做的事,但这可能取决于你到目前为止写了什么。在xslt中,可以推式(应用模板)或拉式(针对每个模板)。如何处理节点?您可以发布xslt中处理
id
节点的部分吗?您好,谢谢您的回复。我已经插入了与“id”匹配的片段,但是输出xml文件仍然将“id”、“address”、“phone”显示为“info”的子项(并且只有在删除“address”和“phone”节点时才显示“id”)。我对XSLT非常陌生,可能会错误地解释问题或提供不完整的信息,我对此表示歉意。到目前为止,我还没有听说过以下兄弟姐妹,因此我将对此进行调查。@user3860417如果不查看XSLT代码,很难说出问题所在,因此最好也将当前代码添加到问题中。我的代码依赖于在身份转换模板上,因此,如果您的代码中没有该选项,您也可以尝试将
替换为
。嗨,Eero-首先,为您上面的姓名输入错误道歉。其次,我已用解决方案更新了问题。谢谢您的帮助!
  <xsl:template match="id">
    <xsl:copy>
      <xsl:apply-templates select="@* | following-sibling::*/>
    </xsl:copy>
  </xsl:template>
<info>
  <id name="Tim">
    <address addr="1 Witchwood Close"/>
    <phone num="01234 567 891"/>
  </id>
  <address addr="1 Witchwood Close"/>
  <phone num="01234 567 891"/>
</info?
following-sibling::*|@*
<xsl:template match="id">
  <xsl:copy>
    <xsl:apply-templates select="@name | following-sibling::*//@addr"/>
    <xsl:apply-templates select="@name | @addr | following-sibling::*//@num"/>
  </xsl:copy>
</xsl:template>
<info>
  <id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
</info>
<info>
  <id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
  <address addr="1 Witchwood Close"/>
</info>
<xsl:stylesheet version="1.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:template match="id">
    <xsl:copy>
      <!--
      Apply the attributes of the current node and the attributes of all
      following siblings (in this case, <address> and <phone>)
      -->
      <xsl:apply-templates select="@* | following-sibling::*/@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Drop the <address> and <phone> elements -->
  <xsl:template match="address | phone"/>

  <!--
  Identity transform: copy attributes and elements from input document to output
  document as is
  -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>