XML to XML с использованием XSLT
Я пытаюсь создать новый XML-файл из существующего, используя XSL. При записи нового файла я хочу замаскировать данные, появляющиеся в поле accountname.
Вот как выглядит мой XML:
<?xml version="1.0" encoding="UTF-8"?>
<Sumit>
<AccountName>Sumit</AccountName>
<CCT_datasetT id="Table">
<row>
<CCTTitle2>Title</CCTTitle2>
</row>
</CCT_datasetT>
</Sumit>
Вот мой XSL-код:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute namespace="{namespace-uri()}" name="{name()}"/>
</xsl:template>
<xsl:template match="AccountName">
<AccountName>acc_no</AccountName>
</xsl:template>
</xsl:stylesheet>
Когда я применяю код XSL к моему XML, я получаю следующий результат:
<?xml version="1.0" encoding="UTF-16"?>
<Sumit>
<AccountName>acc_no</AccountName>
<CCT_datasetT id="">
<row>
<CCTTitle2>Title</CCTTitle2>
</row>
</CCT_datasetT>
</Sumit>
Со следующими вопросами:
1) он создает выходные данные, используя кодировку UTF-16
2) Вывод второй строки это:
<CCT_datasetT id="">
Значение атрибута (таблица) отсутствует.
Может ли кто-нибудь, пожалуйста, сказать мне, как мне избавиться от этих двух проблем. Большое спасибо.
@Evan Lenz:
Вот код javascript:
var oArgs = WScript.Arguments;
if (oArgs.length == 0)
{
WScript.Echo ("Usage : cscript xslt.js xml xsl");
WScript.Quit();
}
xmlFile = oArgs(0) + ".xml";
xslFile = oArgs(1) + ".xsl";
var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load(xmlFile)
// Load the XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(xslFile)
// Transform
var msg = xml.transformNode(xsl)
var fso = new ActiveXObject("Scripting.FileSystemObject");
// Open the text file at the specified location with write mode
var txtFile = fso.OpenTextFile("Output.xml", 2, false, 0);
txtFile.Write(msg);
txtFile.close();
Он создает вывод в новом файле " Output.xml", но я не знаю, почему меняется кодировка. Меня это больше беспокоит по следующей причине:
Мой входной XML-код содержит следующий код:
<Status></Status>
И в выводе его появляется как
<Status>
</Section>
Возврат каретки вводится для всех пустых тегов. Я не уверен, имеет ли это какое-то отношение к кодировке. Пожалуйста, предложите.
Большое Спасибо.
2 ответов:
Удалите второе правило шаблона. Первое правило шаблона (правило идентификации) уже будет копировать атрибуты для вас. Включив второй (который имеет явную инструкцию
<xsl:attribute>), вы создаете конфликт-условие ошибки, и процессор XSLT восстанавливается, выбирая тот, который появляется позже в вашей таблице стилей. Причина, по которой атрибут "id" пуст, заключается в том, что ваше второе правило создает новый атрибут с тем же именем, но без значения. Но опять же, это второе правило ненужный в любом случае, так что вы должны просто удалить его. Это решит проблему отсутствия значения атрибута.Что касается выходной кодировки, похоже, что ваш процессор XSLT не соблюдает директиву
<xsl:output>, которую вы ему дали, или она вызывается в контексте (например, на стороне сервера?) где кодирование определяется фреймворком, а не кодом XSLT. Какой процессор XSLT вы используете и как вы вызываете его?Обновление (re: кодировка символов):
В метод сохранения (DOMDocument) документация гласит следующее:
Кодировка символов основана на атрибуте encoding в XML-объявлении, например<?xml version="1.0" encoding="windows-1252"?>. Если атрибут кодировки не указан, по умолчанию используется UTF-8.Я бы попробовал использовать transformNodeToObject () и save () Вместо вывода в строку.
Я не проверял это, но вы, вероятно, хотите что-то вроде этого:
var result = new ActiveXObject("Microsoft.XMLDOM") // Transform xml.transformNodeToObject(xsl, result); result.save("Output.xml");Обновление (re: ненужные пробелы):
Если вы хотите иметь полный контроль над тем, какие пробелы появляются в результате, вы не должны указывать indent="yes" на элементе
<xsl:output>. Попробуйте удалить это.
Попробуйте это:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- You don't actually need this template --> <!-- but I think this was what you were trying to do --> <xsl:template match="@*" priority="2"> <xsl:attribute namespace="{namespace-uri()}" name="{name()}"><xsl:value-of select="."/></xsl:attribute> </xsl:template> <xsl:template match="AccountName" priority="2"> <AccountName>acc_no</AccountName> </xsl:template> </xsl:stylesheet>Что касается вопроса UTF, вы поступаете правильно.
От www.w3.org/TR/xslt: Атрибут encoding указывает предпочтительную кодировку для вывода результирующего дерева. Процессоры XSLT должны соблюдать значения UTF-8 и UTF-16.
Comments