2014-01-09 3 views
0

У меня проблема, когда ничего не заменяют.Переименование узлов XML и замена значений с помощью XSL

Я рассмотрел другие проблемы SO до rename nodes и до replace values и скопировал примеры из ответов, но для меня ничего не работает. Я подозреваю, что у меня есть что-то неточно, но я просмотрел свой код C#, XML и XSL и не могу найти его.

Вот мой C# код:

private static string GetOutput(string xmlFileName, string xslFileName) 
{ 
    var xmlDocument = new XmlDocument(); 
    xmlDocument.Load(xmlFileName); 

    var xslTransform = new XslCompiledTransform(); 
    xslTransform.Load(xslFileName); 

    var stream = new MemoryStream(); 
    xslTransform.Transform(xmlDocument, null, stream); 

    stream.Position = 1; 
    var reader = new StreamReader(stream); 
    string output = reader.ReadToEnd(); 

    return output; 
} 

Вот мое содержимое моего файла XML:

<?xml version="1.0" encoding="utf-8" ?> 
<TransformThis xmlns="http://schemas.datacontract.org/2004/07/TransformTest" 
      xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <f_name>John</f_name> 
    <l_name>D&apos;Oh!</l_name> 
    <Version>1.0</Version> 
</TransformThis> 

А вот содержимое моего файла XSL:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       exclude-result-prefixes="msxsl"> 

    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="Version/text()[.='1.0']">1.1</xsl:template> 

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

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

</xsl:stylesheet> 

Когда я запускаю свою программу, результат совпадает с исходным XML. Ни имена f_name и l_name не были переименованы, ни значение узла версии не было заменено.

Любая помощь была бы принята с благодарностью.

UPDATE За ответ michael.hor257k в поле ниже, я изменил мой файл XLS следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:tx="http://schemas.datacontract.org/2004/07/TransformTest" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       exclude-result-prefixes="msxsl"> 

    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="tx:Version/text()[.='1.0']">1.1</xsl:template> 

    <xsl:template match="tx:f_name"> 
     <FirstName> 
      <xsl:apply-templates select="node()|@*"/> 
     </FirstName> 
    </xsl:template> 

    <xsl:template match="tx:l_name"> 
     <LastName> 
      <xsl:apply-templates select="node()|@*"/> 
     </LastName> 
    </xsl:template> 

</xsl:stylesheet> 

Я добавил ... TransformTest имен в файл XLS и приставкой в ​​match узлы с tx:.

Теперь преобразование является работает, но он также добавил ТХ: пространство имен для переименованных узлов:

<?xml version="1.0" encoding="utf-8"?> 
<Transformer xmlns="http://schemas.datacontract.org/2004/07/TransformTest" 
      xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <FirstName xmlns="" xmlns:tx="http://schemas.datacontract.org/2004/07/TransformTest">John</FirstName> 
    <LastName xmlns="" xmlns:tx="http://schemas.datacontract.org/2004/07/TransformTest">Doh</LastName> 
    <Version>1.1</Version> 
</Transformer> 

Кроме того, когда XML десериализации в объект, свойства LastName и FirstName являются null, который, как я подозреваю, имеет какое-то отношение к дополнительным атрибутам пространства имен на этих узлах.

Я хотел бы, чтобы результат выглядел так же, как и исходный XML, но только с измененными именами и значениями.

UPDATE # 2 michael.hor257k ДОБАВЛЕНО: пример XLS-файл в своем ответе. Это решило все мои проблемы.

ответ

1

Ни имена узлов f_name и l_name не были переименованы, ни значение узла версии .

Эти элементы являются дочерними элементами элемента <TransformThis>, который имеет собственное пространство имен. Вы должны объявить это пространство имен в своей таблице стилей, назначить ему префикс и использовать префикс при обращении к элементу или его потомкам.


ДОБАВЛЕНО:
Попробуйте это так? Обратите внимание, что это немного сложно, потому что вы по существу добавляете новых детей к существующим (скопированным) родителям.Эти новые элементы автоматически не наследуют пространство имен их приемного родителя, и им необходимо, чтобы он был назначен им явно.

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns="http://schemas.datacontract.org/2004/07/TransformTest" 
exclude-result-prefixes="ns"> 

<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

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

<xsl:template match="ns:Version/text()[.='1.0']">1.1</xsl:template> 

<xsl:template match="ns:f_name"> 
    <xsl:element name="FirstName" namespace="http://schemas.datacontract.org/2004/07/TransformTest"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="ns:l_name"> 
    <xsl:element name="LastName" namespace="http://schemas.datacontract.org/2004/07/TransformTest"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 
+0

Спасибо, @ Michael.hor257k. Я знал, что делаю что-то не так. Можете ли вы привести пример? –

+0

@ Weltonv3.53 Вы хотите сохранить исходное пространство имен в результате? –

+0

Да, если это возможно. Я немного экспериментировал и добавил пространство имен XML-файла в XSL и префикс имен узлов, а _did_ заменил имена и значения узлов, но также добавил пространство имен к переименованным узлам. Затем, когда я десериализовал XML в объект, значения для этих узлов отсутствовали. В идеале я хотел бы, чтобы результат выглядел так же, как оригинальный XML, но только с измененными именами и значениями. –

Смежные вопросы