我遇到的问题是什么都没有被替换。
我查看了rename nodes和replace values的其他SO问题,并复制了答案中的示例,但没有任何内容对我有用。我怀疑我有一些巧妙的错误,但我已经审查了我的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'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节点均未重命名,Version节点值也未被替换。
非常感谢任何帮助。
更新根据下面的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文件中,并使用 tx:为match
节点添加前缀。
现在转换 正在运行,但它也将tx:namespace添加到重命名的节点:
<?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一样,但只更改了名称和值。
更新#2 michael.hor257k ADDED:他答案中的示例XLS文件。这解决了我的所有问题。
答案 0 :(得分: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>