Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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
使用XSLT将XML文件转换为另一个XML文件_Xml_Xslt - Fatal编程技术网

使用XSLT将XML文件转换为另一个XML文件

使用XSLT将XML文件转换为另一个XML文件,xml,xslt,Xml,Xslt,我有一个简单的xml文件,我想使用XSLT进行转换 第一个节点是模式(header),下面的节点是实际数据。请注意,数据中缺少一些字段 <ex:file xmlns:ex="http://example.com"> <ex:header> <ex:title>houseNumber</ex:title> <ex:title>street</ex:title> <ex:title>cit

我有一个简单的xml文件,我想使用XSLT进行转换

第一个节点是模式(header),下面的节点是实际数据。请注意,数据中缺少一些字段

<ex:file xmlns:ex="http://example.com">
  <ex:header>
    <ex:title>houseNumber</ex:title>
    <ex:title>street</ex:title>
    <ex:title>city</ex:title>
    <ex:title>state</ex:title>
  </ex:header>
  <ex:address>
    <ex:field>108</ex:field>
    <ex:field>Ridgewood Circle</ex:field>
    <ex:field>Rochester</ex:field>
    <ex:field>NY</ex:field>
  </ex:address>
  <ex:address>
    <ex:field/>
    <ex:field>W. Clark</ex:field>
    <ex:field>Springfield</ex:field>
    <ex:field>IL</ex:field>
  </ex:address>
</ex:file>

门牌号
街道
城市
状态
108
里奇伍德圆
罗切斯特
纽约
克拉克
斯普林菲尔德
白细胞介素
我们希望以两种方式转换此XML。 首先,我们希望使用“header”中的信息并替换四个ex:field元素,这样我可以得到一个如下所示的XML:

<ex:file xmlns:ex="http://example.com">
  <ex:header>
    <ex:title>houseNumber</ex:title>
    <ex:title>street</ex:title>
    <ex:title>city</ex:title>
    <ex:title>state</ex:title>
  </ex:header>
  <ex:address>
    <ex:houseNumber>108</ex:houseNumber>
    <ex:street>Ridgewood Circle</ex:street>
    <ex:city>Rochester</ex:city>
    <ex:state>NY</ex:state>
  </ex:address>
  <ex:address>
    <ex:houseNumber/>
    <ex:street>W. Clark</ex:street>
    <ex:city>Springfield</ex:city>
    <ex:state>IL</ex:state>
  </ex:address>
</ex:file>

门牌号
街道
城市
状态
108
里奇伍德圆
罗切斯特
纽约
克拉克
斯普林菲尔德
白细胞介素
第二个转换是消除这些空元素:

<ex:file xmlns:ex="http://example.com">
  <ex:header>
    <ex:title>houseNumber</ex:title>
    <ex:title>street</ex:title>
    <ex:title>city</ex:title>
    <ex:title>state</ex:title>
  </ex:header>
  <ex:address>
    <ex:houseNumber>108</ex:houseNumber>
    <ex:street>Ridgewood Circle</ex:street>
    <ex:city>Rochester</ex:city>
    <ex:state>NY</ex:state>
  </ex:address>
  <ex:address>
    <ex:street>W. Clark</ex:street>
    <ex:city>Springfield</ex:city>
    <ex:state>IL</ex:state>
  </ex:address>
</ex:file>

门牌号
街道
城市
状态
108
里奇伍德圆
罗切斯特
纽约
克拉克
斯普林菲尔德
白细胞介素
请注意,第二个“记录”中的“门牌号”已消失

我已经看过XSLT教程()好几次了,我不确定这是否真的可以做到


提前感谢大家。

以下转换解决了您的第一个问题。它是一种身份转换,带有一个附加模板,用于指定对每个
ex:field
元素应执行的操作

XSLT样式表

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

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ex:address">
        <xsl:copy>
            <xsl:for-each select="ex:field">
            <xsl:variable name="pos" select="position()"/>
                <xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
   <ex:header>
      <ex:title>houseNumber</ex:title>
      <ex:title>street</ex:title>
      <ex:title>city</ex:title>
      <ex:title>state</ex:title>
   </ex:header>
   <ex:address>
      <ex:houseNumber>108</ex:houseNumber>
      <ex:street>Ridgewood Circle</ex:street>
      <ex:city>Rochester</ex:city>
      <ex:state>NY</ex:state>
   </ex:address>
   <ex:address>
      <ex:houseNumber/>
      <ex:street>W. Clark</ex:street>
      <ex:city>Springfield</ex:city>
      <ex:state>IL</ex:state>
   </ex:address>
</ex:file>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ex="http://example.com">

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ex:field">
        <xsl:variable name="pos" select="position()"/>
                <xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
    </xsl:template>

    <xsl:template match="ex:field[not(text())]"/>

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
   <ex:header>
      <ex:title>houseNumber</ex:title>
      <ex:title>street</ex:title>
      <ex:title>city</ex:title>
      <ex:title>state</ex:title>
   </ex:header>
   <ex:address>
      <ex:houseNumber>108</ex:houseNumber>
      <ex:street>Ridgewood Circle</ex:street>
      <ex:city>Rochester</ex:city>
      <ex:state>NY</ex:state>
   </ex:address>
   <ex:address>
      <ex:street>W. Clark</ex:street>
      <ex:city>Springfield</ex:city>
      <ex:state>IL</ex:state>
   </ex:address>
</ex:file> 
最终XML输出

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

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ex:address">
        <xsl:copy>
            <xsl:for-each select="ex:field">
            <xsl:variable name="pos" select="position()"/>
                <xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
   <ex:header>
      <ex:title>houseNumber</ex:title>
      <ex:title>street</ex:title>
      <ex:title>city</ex:title>
      <ex:title>state</ex:title>
   </ex:header>
   <ex:address>
      <ex:houseNumber>108</ex:houseNumber>
      <ex:street>Ridgewood Circle</ex:street>
      <ex:city>Rochester</ex:city>
      <ex:state>NY</ex:state>
   </ex:address>
   <ex:address>
      <ex:houseNumber/>
      <ex:street>W. Clark</ex:street>
      <ex:city>Springfield</ex:city>
      <ex:state>IL</ex:state>
   </ex:address>
</ex:file>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ex="http://example.com">

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ex:field">
        <xsl:variable name="pos" select="position()"/>
                <xsl:element name="{concat('ex:',../../ex:header/ex:title[position() = $pos])}">
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
    </xsl:template>

    <xsl:template match="ex:field[not(text())]"/>

</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<ex:file xmlns:ex="http://example.com">
   <ex:header>
      <ex:title>houseNumber</ex:title>
      <ex:title>street</ex:title>
      <ex:title>city</ex:title>
      <ex:title>state</ex:title>
   </ex:header>
   <ex:address>
      <ex:houseNumber>108</ex:houseNumber>
      <ex:street>Ridgewood Circle</ex:street>
      <ex:city>Rochester</ex:city>
      <ex:state>NY</ex:state>
   </ex:address>
   <ex:address>
      <ex:street>W. Clark</ex:street>
      <ex:city>Springfield</ex:city>
      <ex:state>IL</ex:state>
   </ex:address>
</ex:file> 

门牌号
街道
城市
状态
108
里奇伍德圆
罗切斯特
纽约
克拉克
斯普林菲尔德
白细胞介素