繁体   English   中英

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

[英]Renaming XML nodes and replacing values with XSL

我有一个问题,什么也没有被取代。

我研究了其他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&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节点,也没有替换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>

我在XLS文件中添加了... TransformTest命名空间,并为match节点添加了tx:前缀。

现在,转换可以正常工作了,但它也将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,但是只更改了名称和值。

更新#2 michael.hor257k已添加:他的答案中的示例XLS文件。 这解决了我所有的问题。

没有重命名f_name和l_name节点,也没有替换Version节点值。

这些元素是<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>

暂无
暂无

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

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