【问题标题】:Create XML element without closing tag using XSLT使用 XSLT 创建不带结束标记的 XML 元素
【发布时间】:2012-01-01 04:57:37
【问题描述】:

我需要能够使用 XSLT 创建以下格式的 XML 元素:

<element foo="x" bar="y" />

我似乎仅限于:

<element foo="x" bar="y"></element>

原因是我们有一个流程改变,但客户端的接口不能改变。您可能会建议这些本质上是相等的,您是对的,但是我们不能假设我们的客户正在使用合理的 XML 解析技术。

我试过了:

<Mapping>
   <xsl:attribute name="Source">
      <xsl:value-of select="@Source"/>
   </xsl:attribute>
   <xsl:attribute name="Destination">
      <xsl:value-of select="@Destination"/>
   </xsl:attribute>
</Mapping>

这显然添加了不需要的结束标记,并且:

<xsl:element name="Mapping">
   <xsl:attribute name="Source">
      <xsl:value-of select="@Source"/>
   </xsl:attribute>
   <xsl:attribute name="Destination">
      <xsl:value-of select="@Destination"/>
   </xsl:attribute>
 </xsl:element>

这仍然添加了不需要的结束标记。

谁能帮忙?

【问题讨论】:

  • 两者在语义上是相同的。如果您的客户认为这是一种变化,那么这肯定是他们的问题而不是您的问题吗?
  • 您能否向我们展示进行转换的 .NET 代码?没有 XSLT 方法可以强制使用某种格式来序列化空元素,例如&lt;foo/&gt;&lt;foo / 但据我所知.NET 的 XmlWriter 实现默认输出 &lt;foo /&gt; 而不是 &lt;foo&gt;&lt;/foo&gt; 所以我很惊讶你说你得到了带有结束标签的长格式。
  • 谷歌搜索给出了social.msdn.microsoft.com/Forums/en/xmlandnetfx/thread/…。你试过了吗?
  • 客户认为这些不同,这是我们的问题。有多个 PAYING 客户有自己的实现,有些在技术上不是最好的实现方式,但它适用于他们。在对解析 XML 的正确方法提出任何意见之前,这是一天结束时的生意和金钱谈判

标签: c# php asp.net xml xslt


【解决方案1】:

我知道没有办法强制 XSLT 使用简写形式。即使有这样的方法,它也可能是特定于实现的。事实上,如果我在 XMLSpy 中尝试类似您的示例,它实际上使用短符号作为输出,无论我如何设置 xml:space

您可能想检查正在使用的 XSLT 处理器上可以进行哪些设置,以及它是否支持相关的设置。

老实说,如果任何客户端都无法建立 &lt;element/&gt;&lt;element&gt;&lt;/element&gt; 的等价性,那么它就不符合 XML 标准,以至于被破坏了。这是他们的问题,他们应该解决它。

【讨论】:

    【解决方案2】:

    谁能帮忙?

    在 .NET 中 实现这一目标的方法

    编写您自己的派生自 XmlWriter 的类并覆盖 WriteElementString() 方法的所有必要重载,以便您完全控制元素的序列化.

    最后,使用XslCompiledTransform.Transform() 作为参数传递您的类的实例。

    【讨论】:

    • 这样做需要更多的跑腿工作,但比让一线支持团队向我扔订书机和臭鸡蛋要少得多
    • @jaywayco:我们使用的是从 XmlWriter 派生的 XhtmlWriter。是的,很多方法都被覆盖了,但在大多数情况下,覆盖只有几行。一旦你有了这个类,你就可以在任何转换中使用它。
    【解决方案3】:

    这应该不是问题,因为 Joe cmets。但是,您应该能够加载和规范化生成的 XML:

    $str = <<<XML
    <root>
        <element foo="x" bar="y"></element>
    </root>
    XML;
    
    $doc = new DomDocument;
    $doc->loadXML($str);
    echo $doc->saveXML();
    

    输出:

    <?xml version="1.0"?>
    <root>
        <element foo="x" bar="y"/>
    </root>
    

    由于normalizeDocument 函数可以触发加载和保存,因此您可以在完成转换后在代码中添加它。

    【讨论】:

    • 您尝试了哪种变体?您使用的是 PHP 还是 .NET XSLT 处理器?
    【解决方案4】:

    空的 XML 元素以何种方式序列化并不重要,因为任何 XML 解析器都会将它们视为等价的。但是,如果您希望它以不同的方式完成,您可以选择不同的 XSLT 处理器。 Saxon 在 .NET 上可用,如果您切换,您将获得 XSLT 2.0 的所有好处以及解决这个小问题。

    【讨论】:

      【解决方案5】:

      您是否尝试过删除&lt;Mapping&gt;(或&lt;xsl:element name="Mapping"&gt;)和后续元素之后的所有空格? XSLT 引擎可能会将它们视为内容,因此打开一个常规元素只是为了发现没有任何内容可写。

      <xsl:element name="Mapping"><xsl:attribute name="Source"><xsl:value-of select="@Source" /></xsl:attribute></xsl:element>
      

      【讨论】:

        猜你喜欢
        • 2015-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        相关资源
        最近更新 更多