【问题标题】:Issue in converting name/value xml to element xml using xsl使用 xsl 将名称/值 xml 转换为元素 xml 的问题
【发布时间】:2017-06-28 19:20:26
【问题描述】:

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

以下是我的代码文件:

xml 文件:

<?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>

xsl:

<?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 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

我无法找出问题所在。如何在结果 xml 文件中获取键名。任何帮助将不胜感激。提前致谢。

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

 from lxml import etree
 data = open(r'C:\Users\abc\Desktop\input-xsl.xsl')
 xslt_content = data.read()
 xslt_root = etree.XML(xslt_content)
 dom = etree.parse(r'C:\Users\abc\Desktop\input-xml.xml')
 transform = etree.XSLT(xslt_root)
 result = transform(dom)
 print(result)

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    这是因为您的 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>
    

    您在 cmets 中提到您正在使用 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>
    

    【讨论】:

    • 谢谢丹尼尔。但我仍然没有在我的输出 xml 文件中获得标签。我在 python 中运行以下代码来生成我的输出 xml 文件: from lxml import etree data = open(r'C:\Users\anubmand\Desktop\input-xsl.xsl') xslt_content = data.read() xslt_root = etree.XML(xslt_content) dom = etree.parse(r'C:\Users\anubmand\Desktop\input-xml.xml') transform = etree.XSLT(xslt_root) result = transform(dom) print(result)跨度>
    • @starFire - 嗯是的...lxml 不支持 XSLT 2.0。我会修改我的答案。
    猜你喜欢
    • 2014-08-11
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    相关资源
    最近更新 更多