如何用前缀替换 xmlns 名称空间属性?
How can I replace xmlns namespace attributes with prefixes?
我一直在尝试用 C# 编写一个实用程序,它接受一个 XML 文件,从标签中删除 xmlns 属性,在根标签中设置这些属性的前缀,然后在中使用这些前缀标签代替。
源XML文件:
<?xml version="1.0" encoding="utf-8"?>
<Main version="1.0" xmlns="urn:root:v1">
<Report>
<Title>Some Value</Title>
</Report>
<Content>
<Address>
<CountryName xmlns="urn:location:v2">Australia</CountryName>
</Address>
</Content>
</Main>
目标 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<root:Main version="1.0" xmlns:root="urn:root:v1" xmlns:loc="urn:location:v2">
<root:Report>
<root:Title>Some Value</root:Title>
</root:Report>
<root:Content>
<root:Address>
<loc:CountryName>Australia</loc:CountryName>
</root:Address>
</root:Content>
</root:Main>
我已经通过以下代码成功完成了部分工作。我已经用根前缀替换了所有没有属性的标签,并将 xmlns 属性添加到根标签,但是从 CountryName 标签中删除 xmlns 属性并改用那里的前缀并没有成功。
XDocument doc = XDocument.Load(@"C:\Temp\Source.xml");
var content = XElement.Parse(doc.ToString());
content.Attributes("xmlns").Remove();
content.Add(new XAttribute(XNamespace.Xmlns + "root", "urn:root:v1"));
content.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
foreach (var node in doc.Root.Descendants().Where(n => n.Name.NamespaceName == "urn:location:v2"))
{
node.Attribute("xmlns").Remove();
node.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
}
content.Save(@"C:\Temp\Target.xml");
如有任何帮助,我们将不胜感激 - 谢谢!
考虑XSLT, the special-purpose language designed to transform XML files. While I personally do not know or use C#, I do know it can run XSLT 1.0 scripts. See answers here。此外,您选择使用的 XSLT 处理器必须允许此解决方案的 document()
函数。
XSLT (另存为 .xsl 文件;注意在 header 中声明的命名空间)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:root="urn:root:v1" xmlns:local="urn:location:v2">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="root:{name()}" namespace="urn:root:v1">
<xsl:copy-of select="document('')/*/namespace::local"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*[local-name()='CountryName']">
<xsl:element name="local:{name()}" namespace="urn:location:v2">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
C# (见上文link)
var myXslTrans = new XslCompiledTransform();
myXslTrans.Load("XSLTScript.xsl");
myXslTrans.Transform("Input.xml", "Output.xml");
XML输出
<?xml version="1.0"?>
<root:Main xmlns:root="urn:root:v1" xmlns:local="urn:location:v2" version="1.0">
<root:Report>
<root:Title>Some Value</root:Title>
</root:Report>
<root:Content>
<root:Address>
<local:CountryName>Australia</local:CountryName>
</root:Address>
</root:Content>
</root:Main>
你不是在一百万英里之外。您需要做的就是删除任何现有的命名空间声明属性,然后将您想要的属性添加到根目录中。剩下的就交给你了。
var doc = XDocument.Load(@"C:\Temp\Source.xml");
doc.Descendants().Attributes().Where(x => x.IsNamespaceDeclaration).Remove();
doc.Root.Add(new XAttribute(XNamespace.Xmlns + "root", "urn:root:v1"));
doc.Root.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
doc.Save(@"C:\Temp\Target.xml");
有关演示,请参阅 this fiddle。
我一直在尝试用 C# 编写一个实用程序,它接受一个 XML 文件,从标签中删除 xmlns 属性,在根标签中设置这些属性的前缀,然后在中使用这些前缀标签代替。
源XML文件:
<?xml version="1.0" encoding="utf-8"?>
<Main version="1.0" xmlns="urn:root:v1">
<Report>
<Title>Some Value</Title>
</Report>
<Content>
<Address>
<CountryName xmlns="urn:location:v2">Australia</CountryName>
</Address>
</Content>
</Main>
目标 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<root:Main version="1.0" xmlns:root="urn:root:v1" xmlns:loc="urn:location:v2">
<root:Report>
<root:Title>Some Value</root:Title>
</root:Report>
<root:Content>
<root:Address>
<loc:CountryName>Australia</loc:CountryName>
</root:Address>
</root:Content>
</root:Main>
我已经通过以下代码成功完成了部分工作。我已经用根前缀替换了所有没有属性的标签,并将 xmlns 属性添加到根标签,但是从 CountryName 标签中删除 xmlns 属性并改用那里的前缀并没有成功。
XDocument doc = XDocument.Load(@"C:\Temp\Source.xml");
var content = XElement.Parse(doc.ToString());
content.Attributes("xmlns").Remove();
content.Add(new XAttribute(XNamespace.Xmlns + "root", "urn:root:v1"));
content.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
foreach (var node in doc.Root.Descendants().Where(n => n.Name.NamespaceName == "urn:location:v2"))
{
node.Attribute("xmlns").Remove();
node.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
}
content.Save(@"C:\Temp\Target.xml");
如有任何帮助,我们将不胜感激 - 谢谢!
考虑XSLT, the special-purpose language designed to transform XML files. While I personally do not know or use C#, I do know it can run XSLT 1.0 scripts. See answers here。此外,您选择使用的 XSLT 处理器必须允许此解决方案的 document()
函数。
XSLT (另存为 .xsl 文件;注意在 header 中声明的命名空间)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:root="urn:root:v1" xmlns:local="urn:location:v2">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="root:{name()}" namespace="urn:root:v1">
<xsl:copy-of select="document('')/*/namespace::local"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*[local-name()='CountryName']">
<xsl:element name="local:{name()}" namespace="urn:location:v2">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
C# (见上文link)
var myXslTrans = new XslCompiledTransform();
myXslTrans.Load("XSLTScript.xsl");
myXslTrans.Transform("Input.xml", "Output.xml");
XML输出
<?xml version="1.0"?>
<root:Main xmlns:root="urn:root:v1" xmlns:local="urn:location:v2" version="1.0">
<root:Report>
<root:Title>Some Value</root:Title>
</root:Report>
<root:Content>
<root:Address>
<local:CountryName>Australia</local:CountryName>
</root:Address>
</root:Content>
</root:Main>
你不是在一百万英里之外。您需要做的就是删除任何现有的命名空间声明属性,然后将您想要的属性添加到根目录中。剩下的就交给你了。
var doc = XDocument.Load(@"C:\Temp\Source.xml");
doc.Descendants().Attributes().Where(x => x.IsNamespaceDeclaration).Remove();
doc.Root.Add(new XAttribute(XNamespace.Xmlns + "root", "urn:root:v1"));
doc.Root.Add(new XAttribute(XNamespace.Xmlns + "loc", "urn:location:v2"));
doc.Save(@"C:\Temp\Target.xml");
有关演示,请参阅 this fiddle。