如何使用 XslCompiledTransform 在输出 XML 中获取自关闭标签?

发布于 2024-12-12 08:57:48 字数 2345 浏览 0 评论 0原文

请帮助我...

我已经输入了 XML 文档:

<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Object>
      <GUID>201110180954525010129</GUID>
      <Meta name="FILENAME" format="string" frate="" />
    </Object>
</Root>

我需要将其转换为下一个 xml:

<?xml version="1.0" encoding="UTF-8"?>
<Root> 
    <Object> 
        <GUID>201110180954525010129</GUID>
        <FILENAME/> 
    </Object>
<Root>

我已经创建了下一个样式表:

<?xml version="1.0" encoding="utf-8"?>
<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:template match="/">
<xsl:element name="Root">

<xsl:for-each select="Root/Object">
<xsl:element name="Object">

<xsl:element name="FILENAME">
        <xsl:value-of select="Meta[@name='FILENAME']" />
</xsl:element>

<xsl:element name="GUID">
        <xsl:value-of select="GUID" />
</xsl:element>

</xsl:element>
</xsl:for-each>

</xsl:element>
</xsl:template>
</xsl:stylesheet>

但是当我尝试转换它时,我得到了下一个结果:

<?xml version="1.0" encoding="UTF-8"?>
<Root> 
    <Object> 
    <GUID>201110180954525010129</GUID>
        <FILENAME> </FILENAME> 
    </MAObject>
<Root>

我如何告诉解释自闭合标签 ?

C#转换代码:

        var stylesheet = "styleSheet.xml";
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load("input.xml");
        XslCompiledTransform xslTransform = new XslCompiledTransform();
        xslTransform.Load(styleSheet);

            XmlDocument xmlDocumentOutput = new XmlDocument();
            XmlDeclaration xmlDocumentOutputDeclaration = xmlDocumentOutput.CreateXmlDeclaration("1.0", "utf-8", null);
            xmlDocumentOutput.AppendChild(xmlDocumentOutputDeclaration);

            using (XmlWriter xmlWriter = xmlDocumentOutput.CreateNavigator().AppendChild())
            {
                xslTransform.Transform(xmlDocument.CreateNavigator(), null, xmlWriter);
            }

            return xmlDocumentOutput;

Please help me...

I have input XML document:

<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Object>
      <GUID>201110180954525010129</GUID>
      <Meta name="FILENAME" format="string" frate="" />
    </Object>
</Root>

I need to transform it into the next xml:

<?xml version="1.0" encoding="UTF-8"?>
<Root> 
    <Object> 
        <GUID>201110180954525010129</GUID>
        <FILENAME/> 
    </Object>
<Root>

I've created the next style sheet:

<?xml version="1.0" encoding="utf-8"?>
<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:template match="/">
<xsl:element name="Root">

<xsl:for-each select="Root/Object">
<xsl:element name="Object">

<xsl:element name="FILENAME">
        <xsl:value-of select="Meta[@name='FILENAME']" />
</xsl:element>

<xsl:element name="GUID">
        <xsl:value-of select="GUID" />
</xsl:element>

</xsl:element>
</xsl:for-each>

</xsl:element>
</xsl:template>
</xsl:stylesheet>

But when I trying to transform it, I get the next result:

<?xml version="1.0" encoding="UTF-8"?>
<Root> 
    <Object> 
    <GUID>201110180954525010129</GUID>
        <FILENAME> </FILENAME> 
    </MAObject>
<Root>

How can I tell to interpret self-closing tags ?

C# transformation code:

        var stylesheet = "styleSheet.xml";
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load("input.xml");
        XslCompiledTransform xslTransform = new XslCompiledTransform();
        xslTransform.Load(styleSheet);

            XmlDocument xmlDocumentOutput = new XmlDocument();
            XmlDeclaration xmlDocumentOutputDeclaration = xmlDocumentOutput.CreateXmlDeclaration("1.0", "utf-8", null);
            xmlDocumentOutput.AppendChild(xmlDocumentOutputDeclaration);

            using (XmlWriter xmlWriter = xmlDocumentOutput.CreateNavigator().AppendChild())
            {
                xslTransform.Transform(xmlDocument.CreateNavigator(), null, xmlWriter);
            }

            return xmlDocumentOutput;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

漫雪独思 2024-12-19 08:57:48

我使用 XslCompiledTransform 尝试了我们的示例,我得到的输出是

<Root>
  <Object>
    <FILENAME></FILENAME>
    <GUID>201110180954525010129</GUID>
  </Object>
</Root>

How do you run the conversion恰好,你如何看待输出?
使用 XML,空的“foo”元素可以标记为 ,这些形式在语义上是等价的。为什么需要特定的表格? XSLT 转换的输出是否未由 XML 解析器处理?

[编辑]尝试替换

<xsl:element name="FILENAME">
        <xsl:value-of select="Meta[@name='FILENAME']" />
</xsl:element>

<FILENAME>
  <xsl:if test="normalize-space(Meta[@name='FILENAME'])">
    <xsl:value-of select="Meta[@name='FILENAME']"/>
  </xsl:if>
</FILENAME>

至少是否确保您获得的 FILENAME 元素为空。

I tried our samples with XslCompiledTransform, the output I get is

<Root>
  <Object>
    <FILENAME></FILENAME>
    <GUID>201110180954525010129</GUID>
  </Object>
</Root>

How do you run the transformation exactly, how do you look at the output?
With XML an empty "foo" element can be marked up as <foo></foo> or <foo/> or <foo />, these forms are semantically equivalent. Why do you need a particular form? Is the output of the XSLT transformation not processed by an XML parser?

[edit]Try whether replacing

<xsl:element name="FILENAME">
        <xsl:value-of select="Meta[@name='FILENAME']" />
</xsl:element>

with

<FILENAME>
  <xsl:if test="normalize-space(Meta[@name='FILENAME'])">
    <xsl:value-of select="Meta[@name='FILENAME']"/>
  </xsl:if>
</FILENAME>

at least ensures the FILENAME element you get is empty.

樱娆 2024-12-19 08:57:48

尝试删除模板中与 FILENAME 匹配的 周围的换行符(以及任何其他空格)。它们是显示在结果中的文本节点。

Try removing the linebreaks (and any other whitespace) around <xsl:value-of> in the template that matches FILENAME. They are text nodes that show up in the result.

佼人 2024-12-19 08:57:48

我不知道它是否会产生任何影响,但尝试一下这个样式表,它具有针对带有和不带有数据的 Meta 的单独匹配模板。如果不出意外的话,它是建立在身份模板之上的,因此无需在原始 XSLT 中硬编码如此多的元素名称。

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

   <xsl:template match="Meta">
      <xsl:element name="{@name}" />
   </xsl:template>

   <xsl:template match="Meta[. != '']">
      <xsl:element name="{@name}">
         <xsl:apply-templates select="node()"/>
      </xsl:element>
   </xsl:template>

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

当我对此进行测试时,我得到以下结果:

<Root>
   <Object>
      <GUID>201110180954525010129</GUID>
      <FILENAME/>
   </Object>
</Root>

I don't know if it will make any difference, but try this stylesheet, which has separate matching templates for the Meta with and without data. If nothing else, it is built on the identity template and so removes the need for hard-coding so many element names in your original XSLT

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

   <xsl:template match="Meta">
      <xsl:element name="{@name}" />
   </xsl:template>

   <xsl:template match="Meta[. != '']">
      <xsl:element name="{@name}">
         <xsl:apply-templates select="node()"/>
      </xsl:element>
   </xsl:template>

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

When I test this, I get the following result:

<Root>
   <Object>
      <GUID>201110180954525010129</GUID>
      <FILENAME/>
   </Object>
</Root>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文