在 Net Core 中向 XML 添加不同的命名空间前缀和属性

Add different Namespace prefixes and attributes to XML in Net Core

提问人:prezequias 提问时间:4/26/2023 最后编辑:prezequias 更新时间:4/28/2023 访问量:117

问:

我想在 Net6 Core API 中向现有 XML 添加多个命名空间前缀和属性。 我有以下几点:

<?xml version="1.0" encoding="UTF-8"?>
<note xmlns="http://test.co.uk" xmlns:temp="http://tes007.co.uk" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header>
    <Title>Hello</Title>
  </Header>
  <PutData>
  <Credentials>
    <Username>Test</Username>
    <Password>1234</Password>
  </Credentials>
  <Payload>
      <Filename>test.xml</Filename>
      <FileType>Xml</FileType>
  </Payload>
  <message>
     <title>Title1</title>
     <body></body>
  </message>
  </PutData>
</note>

我想实现的是:

<?xml version="1.0" encoding="UTF-8"?>
<note xmlns="http://test.co.uk" xmlns:temp="http://tes007.co.uk" xmlns:xsi="http://test0010.com.br">
  <xsi:Header>
    <Title>Hello</Title>
  </xsi:Header>
  <temp:PutData>
  <Credentials>
    <Username>Test</Username>
    <Password>1234</Password>
  </Credentials>
  <Payload>
      <Filename>test.xml</Filename>
      <FileType>Xml</FileType>
  </Payload>
  <message Type="TEST007">
     <title>Title1</title>
     <body></body>
  </message>
  </temp:PutData>
</note>

我尝试过这样的方法:


XmlDocument doc = XmlDocument.LoadXml(xml);
var xPath = "//*"  //all nodes
foreach(XmlElement node in doc.SelectNodes(xPath))
{
   if(node.Name == "Header")
    {
       node.Prefix = "xsi";
       node.RemoveAttribute("xmlns");
    }
   if(node.Name == "PutData")
    {
       node.Prefix = "temp";
       node.RemoveAttribute("xmlns");
    }
}

以上部分适用于前缀。

我知道我们有类似的问题,但没有一个对我有用。我很感激任何帮助,谢谢。

C# XML XSD XML 解析

评论

1赞 kjhughes 4/27/2023
(1)你想要的格式不正确,因为它的开始和结束标签不匹配。(2)永远不要说“没有人对我有用”;展示你尝试了什么,结果是什么,以及结果与你的目标有何不同。(3)不要像这样对随机命名空间使用命名空间前缀;它通常保留给 .(4) 如果没有一个最小的可重现示例,这读起来就像一个为我编写代码的请求,这在这里不会很好地结束。xsihttp://www.w3.org/2001/XMLSchema-instance
0赞 Serge 4/27/2023
“我有以下内容:”您是从 API 获取的还是使用 c# 创建的?请向我们展示代码
0赞 prezequias 4/27/2023
嗨,我是用 C# 创建的。首先获取有效负载请求并将其转换为 Json 对象,然后转换为 XML 文件。谢谢你的提问。
0赞 prezequias 4/27/2023
嗨,kjhughes,对不起,xml mal formation,我有点匆忙,因为我需要尽快解决这个问题。我已经编辑了它。
0赞 Yitzhak Khabinsky 4/27/2023
.Net Framework 支持现成的 XSLT 1.0。就像@MichaelKay已经指出的那样,最好使用 XSLT 来完成任务。

答:

0赞 Michael Kay 4/27/2023 #1

下面的 XSLT 3.0 转换更改 PutData 元素的命名空间,并保持其他所有内容不变:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="3.0">
  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:template match="*:PutData">
    <xsl:element name="temp:PutData" namespace="http://tes007.co.uk">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
</xsl:transform>

如果您更喜欢坚持使用 Microsoft 提供的工具,也可以使用 XSLT 1.0 完成此操作。

评论

0赞 prezequias 4/27/2023
谢谢迈克尔,但我正在寻找使用 C# 的东西,例如:XmlDocument
0赞 Michael Kay 4/27/2023
如果你想用艰难的方式去做,恐怕你必须找别人来帮助你。
0赞 mamift 4/28/2023 #2

正如评论者指出的那样,在 .NET 中使用 API 更改元素的名称/命名空间不能做你想做的事,你必须使用 API(等):System.XmlSystem.Xml.LinqXDocumentXElement

var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <note xmlns=\"http://test.co.uk\" xmlns:temp=\"http://tes007.co.uk\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <Header> <Title>Hello</Title> </Header> <PutData> <Credentials> <Username>Test</Username> <Password>1234</Password> </Credentials> <Payload> <Filename>test.xml</Filename> <FileType>Xml</FileType> </Payload> <message> <title>Title1</title> <body></body> </message> </PutData> </note>";
var xdoc = XDocument.Parse(xml);
var xdocAttributes = xdoc.Root.Attributes();
var xsiNs = xdocAttributes.First(n => n.Name.LocalName == "xsi");
var tempNs = xdocAttributes.First(n => n.Name.LocalName == "temp");
xsiNs.Value = "http://test0010.com.br";

var header = xdoc.Descendants().First(d => d.Name.LocalName == "Header");
header.Name = XName.Get("Header", xsiNs.Value);

var putData = xdoc.Descendants().First(d => d.Name.LocalName == "PutData");
putData.Name = XName.Get("PutData", tempNs.Value);

var message = xdoc.Descendants().First(m => m.Name.LocalName == "message");
message.Add(new XAttribute("Type", "TEST007"));

使用将为您提供:xdoc.ToString()

<note xmlns="http://test.co.uk" xmlns:temp="http://tes007.co.uk" xmlns:xsi="http://test0010.com.br">
  <xsi:Header>
    <Title>Hello</Title>
  </xsi:Header>
  <temp:PutData>
    <Credentials>
      <Username>Test</Username>
      <Password>1234</Password>
    </Credentials>
    <Payload>
      <Filename>test.xml</Filename>
      <FileType>Xml</FileType>
    </Payload>
    <message Type="TEST007">
      <title>Title1</title>
      <body></body>
    </message>
  </temp:PutData>
</note>