简体   繁体   English

重命名XML节点并用XSL替换值

[英]Renaming XML nodes and replacing values with XSL

I am having a problem where nothing is being replaced. 我有一个问题,什么也没有被取代。

I looked at other SO issues to rename nodes and to replace values , and have copied the examples from the answers, but nothing is working for me. 我研究了其他SO问题来重命名节点替换值 ,并复制了答案中的示例,但是没有任何结果适合我。 I suspect that I have something subtly wrong, but I have reviewed my C#, XML, and XSL code, and can't seem to find it. 我怀疑我有一些细微的错误,但是我已经查看了我的C#,XML和XSL代码,但似乎找不到。

Here is my C# code: 这是我的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;
}

Here is my the contents of my XML file: 这是我的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>

And here is the contents of my XSL file: 这是我的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>

When I run my program, the output is the same as the original XML. 当我运行程序时,输出与原始XML相同。 Neither the f_name and l_name nodes have been renamed, nor has the Version node value been replaced. 没有重命名f_name和l_name节点,也没有替换Version节点值。

Any help would be greatly appreciated. 任何帮助将不胜感激。

UPDATE Per michael.hor257k's answer below, I have modified my XLS file as follows: 更新下面的每个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>

I added the ...TransformTest namespace to the XLS file, and prefixed the match nodes with tx: . 我在XLS文件中添加了... TransformTest命名空间,并为match节点添加了tx:前缀。

Now the transformation is working, but it is also added the tx: namespace to the renamed nodes: 现在,转换可以正常工作了,但它也将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>

Also, when the XML is deserialized into an object, the LastName and FirstName properties are null, which I suspect has something to do with the additional namespace attributes on those nodes. 另外,当将XML反序列化为对象时,LastName和FirstName属性为null,我怀疑这与这些节点上的其他名称空间属性有关。

I would like the output to look just like the original XML, but with only the names and values changed. 我希望输出看起来像原始的XML,但是只更改了名称和值。

UPDATE #2 michael.hor257k ADDED: an example XLS file in his answer. 更新#2 michael.hor257k已添加:他的答案中的示例XLS文件。 This resolved all of my issues. 这解决了我所有的问题。

Neither the f_name and l_name nodes have been renamed, nor has the Version node value been replaced. 没有重命名f_name和l_name节点,也没有替换Version节点值。

These elements are children of the <TransformThis> element which has its own namespace. 这些元素是<TransformThis>元素的子元素,该元素具有自己的名称空间。 You must declare this namespace in your stylesheet, assign it a prefix and use the prefix when addressing the element or its descendants. 您必须在样式表中声明此名称空间,为其分配前缀,并在寻址元素或其后代时使用该前缀。


ADDED: 添加:
Try it this way? 这样尝试吗? Note that this is a bit tricky, because you are essentially adding new children to an existing (copied) parent. 请注意,这有点棘手,因为您实际上是将新的子代添加到现有(复制的)父代中。 These new elements do not automatically inherit the namespace of their adoptive parent, and they need to have it assigned to them explicitly. 这些新元素不会自动继承其继承父级的命名空间,因此需要将其显式分配给它们。

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM