Как я могу получить самозакрывающиеся теги в выходном XML с помощью XslCompiledTransform?

Пожалуйста помогите...

У меня есть входной 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;

person alex.mironov    schedule 26.10.2011    source источник


Ответы (3)


Я попробовал наши образцы с помощью XslCompiledTransform, и получил следующий результат:

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

Как именно выполнить преобразование, как посмотреть на результат? В XML пустой элемент «foo» может быть помечен как <foo></foo>, <foo/> или <foo />, эти формы семантически эквивалентны. Зачем вам нужна конкретная форма? Выходные данные преобразования XSLT не обрабатываются анализатором XML?

[edit] Попробуйте заменить

<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 пуст.

person Martin Honnen    schedule 26.10.2011
comment
Привет! Спасибо за ответ. Я только что обновил вопрос ... Я действительно не понимаю, почему у меня появляется пробел между тегами ‹FILENAME› ‹/FILENAME› - person alex.mironov; 26.10.2011

Попробуйте удалить разрывы строк (и любые другие пробелы) вокруг <xsl:value-of> в шаблоне, который соответствует FILENAME. Это текстовые узлы, которые отображаются в результате.

person Dabbler    schedule 26.10.2011

Я не знаю, будет ли это иметь какое-либо значение, но попробуйте эту таблицу стилей, в которой есть отдельные шаблоны соответствия для 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>
person Tim C    schedule 26.10.2011