XML - XSLT - 使用第二个 xml 文档向 xml 文档添加新元素

XML - XSLT - Adding new element to xml document with second xml document

这个问题我已经有一段时间了,我无法解决,所以我决定在这里post,

我有以下简单的 XML 输入文档:

<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
    <text-prop name="docName">firstDoc</text-prop>
    <body>
        <column id="17"/>
        <column id="18"/>
        <column id="19"/>
    </body>
</doc1>

我想添加两个新元素,一个是 <elements>,里面有 <element>。然后我还想添加一个 <newColumn> 元素,它是 <body> 元素的子元素。所以我想要得到的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
    <text-prop name="docName">firstDoc</text-prop>
   <elements>
      <element name="first element"/>
   </elements>
    <body>
        <column id="17"/>
        <column id="18"/>
        <column id="19"/>
      <newColumn name="dataSet">first element</newColumn>
    </body>
</doc1>

这是我正在使用的 XSLT 样式表,基于@Martin Honnen 在相关 post 中给我的样式表:

<?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"
    xpath-default-namespace="http://www.eclipse.org/birt/2005/design"
    xmlns="http://www.eclipse.org/birt/2005/design"
    exclude-result-prefixes="xs"
    expand-text="yes"
    version="3.0">


  <xsl:param name="doc2" xmlns="">
<doc2>
    <elemList1>
        <elem1 ID="001" name="firstDoc" />
        <elem1 ID="002" name="secondDoc"/>
    </elemList1>
    <elemList2>
        <elem2 elemID="001">
                <elemData name="first element"/>
        </elem2>
        <elem2 elemID="002">
                <elemData name="second element"/>
        </elem2>
    </elemList2>
</doc2>      
  </xsl:param>

  <xsl:output indent="yes" cdata-section-elements="xml-prop"/>

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

  <xsl:key name="layout-ref" match="elem1" use="@name" xpath-default-namespace=""/>
  <xsl:key name="report-ref" match="elem2" use="@elemID" xpath-default-namespace=""/>

  <xsl:template match="doc1/text-prop[@name = 'docName']">
      <xsl:next-match/>

      <xsl:variable name="layout" select="key('layout-ref', ., $doc2)"/>
      <xsl:variable name="report" select="key('report-ref', $layout/@ID, $doc2)"/>

      <elements>
          <xsl:apply-templates select="$report//elemData" xpath-default-namespace=""/>
      </elements>

  </xsl:template>

  <xsl:template match="elemData" xpath-default-namespace="">
      <element name="{@name}"/>
  </xsl:template>

  <!--HERE IT STOPS WORKING-->

  <xsl:template match="doc1/body/column[last()]" >
      <xsl:next-match/>
      <xsl:variable name="layout2" select="key('layout-ref', ., $doc2)"/>
      <xsl:variable name="report2" select="key('report-ref', $layout2/@ID, $doc2)"/>

      <newColumn name="dataSet">
          <xsl:value-of select="$report2/elemData/@name" xpath-default-namespace=""/>
      </newColumn>

  </xsl:template>


</xsl:stylesheet>

所以我实际得到的结果是这个:

<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
    <text-prop name="docName">firstDoc</text-prop>
   <elements>
      <element name="first element"/>
   </elements>
    <body>
        <column id="17"/>
        <column id="18"/>
        <column id="19"/>
      <newColumn name="dataSet"/>
    </body>
</doc1>

基本上我希望元素 <newColumn> 的值与元素 <element> 的属性 name 的值相同,但我无法访问该值并将其放入 <newColumn> element

如您所见,我能够访问相同的值并将其作为新 <element> 元素的属性。

我不能通过这种方式访问​​我定义为 <xsl:param> (doc2) 的文档吗?

参见 XSLT FIDDLE AT: https://xsltfiddle.liberty-development.net/3NzcBtf/1

谢谢!

亚历山大·哈辛托

看来我猜对了您在评论中想要的内容,我现在 post 将其作为答案,以便您可以将问题标记为已解决。

当你使用键函数时,你需要传入你想要查找的节点的键值,即在match="doc1/text-prop[@name = 'docName']"中你传入key('layout-ref', ., $doc2)这是字符串值(例如 firstDoc)匹配的 text-prop 元素。在您的 match="doc1/body/column[last()]" 列元素中没有该字符串值(您的列为空),因此从您的问题中不太清楚您希望如何将列与其他元素相关联,除非您想导航到key('layout-ref', ancestor::doc1/text-prop[@name = 'docName'], $doc2).