Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何使用xslt在父级<;元素>;可能有孩子<;元素>;这需要不同的逻辑_Xml_Xslt - Fatal编程技术网

Xml 如何使用xslt在父级<;元素>;可能有孩子<;元素>;这需要不同的逻辑

Xml 如何使用xslt在父级<;元素>;可能有孩子<;元素>;这需要不同的逻辑,xml,xslt,Xml,Xslt,因此,我正在处理一个结构与此类似的xml文档 原始XML: 正常元素 <element name="Name1"> <document> <number>A1</number> <reference>B1</reference> </document> </element> A1 地下一层 类似分组的元素 (为清晰起见,添加了根元素) A2 地下二层 A3 地下三层

因此,我正在处理一个结构与此类似的xml文档

原始XML:

正常元素

<element name="Name1">
  <document>
    <number>A1</number>
    <reference>B1</reference>
  </document>
</element>

A1
地下一层
类似分组的元素 (为清晰起见,添加了根元素)


A2
地下二层
A3
地下三层
我想从这份文件中得到的是这样的东西

<references>
  <reference>
    <original>A1</original>
    <mapping>B1</mapping>
  </reference>
 <reference>
  <group id="Name2.xxx.Group">
    <reference>
        <original>A2</original>
        <mapping>B2</mapping>
      </reference>
      <reference>
        <original>A3</original>
        <mapping>B3</mapping>
      </reference>
    </group>
  </reference>
</references>

A1
地下一层
A2
地下二层
A3
地下三层
我很难想出一个很好的方法来做到这一点,因为元素上的匹配似乎匹配所有元素

到目前为止,我已经做到了这一点,但意识到它将不起作用,因为父元素和子元素具有相同的名称,但每个元素都需要一些不同的逻辑

<xsl:template match="/">
    <xsl:element name="references">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>
<xsl:template match="element">
    <xsl:element name="reference">
        <xsl:if test="element/document">
            <xsl:element name="original">
                <xsl:value-of select="element/document/number"/>
            </xsl:element>
            <xsl:element name="mapping">
                <xsl:value-of select="element/document/reference"/>
            </xsl:element>
            <xsl:element name="id">
                <xsl:value-of select="@id"/>
            </xsl:element>
        </xsl:if>
    </xsl:element>
</xsl:template>

很难准确回答您的问题,因为您的第二个输入示例不是格式良好的XML(没有单个根元素),并且您的输出显示了来自两个输入示例的数据

以下样式表:

XSLT1.0

<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="/root">
    <references>
        <xsl:apply-templates/>
    </references>
</xsl:template>

<xsl:template match="element[@id]">
    <group id="{@id}">
        <xsl:apply-templates/>
    </group>
</xsl:template>

<xsl:template match="element">
    <reference>
        <original>
            <xsl:value-of select="document/number"/>
        </original>
        <mapping>
            <xsl:value-of select="document/reference"/>     
        </mapping>
    </reference>
</xsl:template>

</xsl:stylesheet>

应用于第一个输入示例时,将返回:

<?xml version="1.0" encoding="UTF-8"?>
<reference>
   <original>A1</original>
   <mapping>B1</mapping>
</reference>

A1
地下一层
当应用于以下已更正的输入示例时

<root>
 <element name="Name2.Group" id="Name2.xxx.Group">
   <element name="Name3">
    <document>
      <number>A2</number>
      <reference>B2</reference>
    </document>
  </element>
  <element name="Name4">
    <document>
      <number>A3</number>
      <reference>B3</reference>
    </document>
  </element>
</element>
</root>

A2
地下二层
A3
地下三层
结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<references>
   <group id="Name2.xxx.Group">
      <reference>
         <original>A2</original>
         <mapping>B2</mapping>
      </reference>
      <reference>
         <original>A3</original>
         <mapping>B3</mapping>
      </reference>
   </group>
</references>

A2
地下二层
A3
地下三层

这类任务的规范方法是应用身份转换,并对输出中看起来不同的节点进行修改

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*" />

    <!-- identity transform - copy everything unless another template fits -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- the document element becomes <references> -->
    <xsl:template match="/*">
        <references>
            <xsl:apply-templates select="@*|node()" />
        </references>
    </xsl:template>

    <!-- <element> becomes <reference> -->
    <xsl:template match="element">
        <reference>
            <xsl:apply-templates select="@*|node()" />
        </reference>
    </xsl:template>

    <!-- <element> with group becomes <group> -->
    <xsl:template match="element[contains(@name, '.Group')]">
        <group>
            <xsl:apply-templates select="@*|node()" />
        </group>
    </xsl:template>

    <!-- we don't want to see element/@name in the output -->
    <xsl:template match="element/@name" /> 

    <!-- <document> is stepped over (just process the children) -->
    <xsl:template match="element/document">
        <xsl:apply-templates select="@*|node()" />
    </xsl:template>

    <!-- <number> becomes <original> -->
    <xsl:template match="element/*/number">
        <original>
            <xsl:apply-templates select="@*|node()" />
        </original>
    </xsl:template>

    <!-- <reference> becomes <mapping> -->
    <xsl:template match="element/*/reference">
        <mapping>
            <xsl:apply-templates select="@*|node()" />
        </mapping>
    </xsl:template>
</xsl:transform>

输出,当应用于

<x>
    <element name="Name1">
      <document>
        <number>A1</number>
        <reference>B1</reference>
      </document>
    </element>
    <element name="Name2.Group" id="Name2.xxx.Group">
       <element name="Name3">
        <document>
          <number>A2</number>
          <reference>B2</reference>
        </document>
      </element>
      <element name="Name4">
        <document>
          <number>A3</number>
          <reference>B3</reference>
        </document>
      </element>
    </element>    
</x>

A1
地下一层
A2
地下二层
A3
地下三层
会是

<references>
   <reference>
      <original>A1</original>
      <mapping>B1</mapping>
   </reference>
   <group id="Name2.xxx.Group">
      <reference>
         <original>A2</original>
         <mapping>B2</mapping>
      </reference>
      <reference>
         <original>A3</original>
         <mapping>B3</mapping>
      </reference>
   </group>
</references>

A1
地下一层
A2
地下二层
A3
地下三层

是的,很抱歉,我试图删去元素的细节,然后用最基本的例子说明我的问题所在。我在xml示例中的意思是假设显示的两个父元素都包装在某个元素中,这意味着它们都在同一个文档中。我试试看
<references>
   <reference>
      <original>A1</original>
      <mapping>B1</mapping>
   </reference>
   <group id="Name2.xxx.Group">
      <reference>
         <original>A2</original>
         <mapping>B2</mapping>
      </reference>
      <reference>
         <original>A3</original>
         <mapping>B3</mapping>
      </reference>
   </group>
</references>