使用xsl将名称/值xml转换为元素xml的问题

时间:2017-06-28 19:20:26

标签: xml xslt xslt-2.0

我想使用xsl将名称/值xml转换为元素xml。我尝试了所有可以找到的方法。我引用了这篇文章Convert Name/Value Pair XML to Elements using XSLT并进行了更改,但我的结果xml没有显示关键值。

以下是我的代码文件:

xml文件:

$segments = $result['segments'];
usort($segments, function ($item1, $item2) {
    if ($item1['name'] == $item2['name']) return 0;
    return $item1['name'] < $item2['name'] ? -1 : 1;
});

的xsl:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<METSM xmlns="metsmng" xmlns:ns2="http://www.w3.org/1999/xlink">
<Case id="MTMzo29276" ns2:href="https://metsm.com/api/case/MTMzo29276">
    <Column name="BU">SU</Column>
    <Column name="Summary">Hardware failure</Column>
    <Column name="Project">Servers</Column>
    <Column name="Priority">High</Column>
    <Column name="Status">Working</Column>
    <Column name="Open-Date">01/23/2017 23:11:16</Column>
</Case>
<Case id="MTMzo29739" ns2:href="https://metsm.com/api/case/MTMzo29739">
    <Column name="BU">AICM</Column>
    <Column name="Summary">Create a new profile</Column>
    <Column name="Project">Datacentre</Column>
    <Column name="Priority">Low</Column>
    <Column name="Status">Open</Column>
    <Column name="Open-Date">10/04/2010 00:00:00</Column>
</Case>
</METSM>

需要输出:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/METSM">
<METSM>
   <xsl:for-each select="Case">
   <Case>
      <xsl:element name="{@id}">
         <xsl:value-of select="."/>
      </xsl:element>
      <xsl:for-each select="Column">
         <xsl:element name="{@name}">
            <xsl:value-of select="."/>
         </xsl:element>
      </xsl:for-each>
   </Case>
</xsl:for-each>
</METSM>
</xsl:template>
</xsl:stylesheet>

我得到的是什么:

<METSM>
<Case>
  <id> MTMzo29276 </id>
  <BU> SU </BU>
  <Summary> Hardware failure </Summary>
  ....
</Case>
<Case>
 ....
</Case>
</METSM>

我无法弄清楚这个问题。如何在结果xml文件中获取密钥名称。任何帮助都将非常感激。提前谢谢。

编辑:使用下面的python代码生成输出xml文件:

<?xml version="1.0" encoding="UTF-8"?>


    SU
    Hardware failed
    Servers
    High
    Working
    01/23/2017 23:11:16


    AICM
    Create a new profile
    Datacentre
    Low
    Open
    10/04/2010 00:00:00

1 个答案:

答案 0 :(得分:0)

这是因为您的XML位于默认命名空间metsmng中。由于您使用的是XSLT 2.0,因此可以使用xpath-default-namespace ...

XSLT 2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xpath-default-namespace="metsmng">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/METSM">
    <METSM>
      <xsl:for-each select="Case">
        <Case>
          <id><xsl:value-of select="@id"/></id>
          <xsl:for-each select="Column">
            <xsl:element name="{@name}">
              <xsl:value-of select="."/>
            </xsl:element>
          </xsl:for-each>
        </Case>
      </xsl:for-each>
    </METSM>
  </xsl:template>
</xsl:stylesheet>

另请注意,我修复了id元素输出。

<强>输出

<METSM>
   <Case>
      <id>MTMzo29276</id>
      <BU>SU</BU>
      <Summary>Hardware failure</Summary>
      <Project>Servers</Project>
      <Priority>High</Priority>
      <Status>Working</Status>
      <Open-Date>01/23/2017 23:11:16</Open-Date>
   </Case>
   <Case>
      <id>MTMzo29739</id>
      <BU>AICM</BU>
      <Summary>Create a new profile</Summary>
      <Project>Datacentre</Project>
      <Priority>Low</Priority>
      <Status>Open</Status>
      <Open-Date>10/04/2010 00:00:00</Open-Date>
   </Case>
</METSM>

您在评论中提到您正在使用lxml。如果是这样,则不支持XSLT 2.0;您需要使用XSLT 1.0。您需要做的是将命名空间绑定到前缀并在XPath中使用该前缀...

XSLT 1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:m="metsmng" exclude-result-prefixes="m">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/m:METSM">
    <METSM>
      <xsl:for-each select="m:Case">
        <Case>
          <id><xsl:value-of select="@id"/></id>
          <xsl:for-each select="m:Column">
            <xsl:element name="{@name}">
              <xsl:value-of select="."/>
            </xsl:element>
          </xsl:for-each>
        </Case>
      </xsl:for-each>
    </METSM>
  </xsl:template>
</xsl:stylesheet>