#xml #xslt #transform #xslcompiledtransform
#xml #xslt #преобразовать #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;
Ответ №1:
Я попробовал наши образцы с помощью XslCompiledTransform, результат, который я получаю,
<Root>
<Object>
<FILENAME></FILENAME>
<GUID>201110180954525010129</GUID>
</Object>
</Root>
Как вы точно выполняете преобразование, как вы смотрите на результат?
В XML пустой элемент «foo» может быть помечен как <foo></foo>
или <foo/>
или <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, который вы получаете, пуст.
Комментарии:
1. Привет! Спасибо за ответ. Я только что обновил вопрос… Я действительно не понимаю, почему я получаю пробелы между тегами <FILENAME> </FILENAME>
Ответ №2:
Попробуйте удалить разрывы строк (и любые другие пробелы) <xsl:value-of>
в соответствующем шаблоне FILENAME
. Это текстовые узлы, которые отображаются в результате.
Ответ №3:
Я не знаю, будет ли это иметь какое-либо значение, но попробуйте эту таблицу стилей, в которой есть отдельные соответствующие шаблоны для метаданных с данными и без данных. Во всяком случае, он построен на шаблоне identity и, таким образом, устраняет необходимость в жестком кодировании такого количества имен элементов в вашем исходном 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>