如何从 XML 文档中删除 2 个父命名空间标记
本文关键字:命名空间 删除 XML 文档 | 更新日期: 2023-09-27 18:37:06
>我有以下XML文档,但我需要删除前两个元素(并保留所有子元素)。我似乎无法使用 XPath 执行此操作,因为它们是命名空间?我不太了解XML文档的这一部分,因此也非常欢迎任何解释。此外,HubChangeRequest 是可变的,所以我不能在代码中使用它 - 我需要基本上删除 2 个父元素。
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<mgns1:PlaceXmlMessage xmlns:mgns1="http://www.testing.com/">
<mgns1:xmlDocument>
<HubChangeRequest version="1.0">
<TransactionReference>
<AuthenticationID>TestSUPPLIERS</AuthenticationID>
<AuthenticationKey>hidden</AuthenticationKey>
<TransactionNumber>hidden</TransactionNumber>
</TransactionReference>
<MessageNumber>hidden</MessageNumber>
<MessageCreatedDate>2016-03-01T12:31:31</MessageCreatedDate>
<ReferenceNumber>ABC123456789</ReferenceNumber>
<ProductDetails>
<StockItem LineReference="123456/1">
<NewStatus>Despatched</NewStatus>
<DespatchReference>3 PARCEL LINE</DespatchReference>
</StockItem>
<StockItem LineReference="123345/2">
<NewStatus>Despatched</NewStatus>
<DespatchReference>3 PARCEL LINE</DespatchReference>
</StockItem>
</ProductDetails>
</HubChangeRequest>
</mgns1:xmlDocument>
</mgns1:PlaceXmlMessage>
需要明确的是,这就是我想要的结局:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<HubChangeRequest version="1.0">
<TransactionReference>
<AuthenticationID>TestSUPPLIERS</AuthenticationID>
<AuthenticationKey>hidden</AuthenticationKey>
<TransactionNumber>hidden</TransactionNumber>
</TransactionReference>
<MessageNumber>hidden</MessageNumber>
<MessageCreatedDate>2016-03-01T12:31:31</MessageCreatedDate>
<ReferenceNumber>ABC123456789</ReferenceNumber>
<ProductDetails>
<StockItem LineReference="123456/1">
<NewStatus>Despatched</NewStatus>
<DespatchReference>3 PARCEL LINE</DespatchReference>
</StockItem>
<StockItem LineReference="123345/2">
<NewStatus>Despatched</NewStatus>
<DespatchReference>3 PARCEL LINE</DespatchReference>
</StockItem>
</ProductDetails>
</HubChangeRequest>
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version='"1.0'" encoding='"UTF-8'" standalone='"no'" ?>" +
"<mgns1:PlaceXmlMessage xmlns:mgns1='"http://www.testing.com/'">" +
"<mgns1:xmlDocument>" +
"<HubChangeRequest version='"1.0'">" +
"<TransactionReference>" +
"<AuthenticationID>TestSUPPLIERS</AuthenticationID>" +
"<AuthenticationKey>hidden</AuthenticationKey>" +
"<TransactionNumber>hidden</TransactionNumber>" +
"</TransactionReference>" +
"<MessageNumber>hidden</MessageNumber>" +
"<MessageCreatedDate>2016-03-01T12:31:31</MessageCreatedDate>" +
"<ReferenceNumber>ABC123456789</ReferenceNumber>" +
"<ProductDetails>" +
"<StockItem LineReference='"123456/1'">" +
"<NewStatus>Despatched</NewStatus>" +
"<DespatchReference>3 PARCEL LINE</DespatchReference>" +
"</StockItem>" +
"<StockItem LineReference='"123345/2'">" +
"<NewStatus>Despatched</NewStatus>" +
"<DespatchReference>3 PARCEL LINE</DespatchReference>" +
"</StockItem>" +
"</ProductDetails>" +
"</HubChangeRequest>" +
"</mgns1:xmlDocument>" +
"</mgns1:PlaceXmlMessage>";
XDocument doc = XDocument.Parse(xml);
XElement placeXmlMessage = (XElement)doc.FirstNode;
XElement secondNode = placeXmlMessage.Elements().FirstOrDefault();
XElement hubChangeRequest = secondNode.Elements().FirstOrDefault();
placeXmlMessage.ReplaceWith(hubChangeRequest);
}
}
}
可以使用 XSLT 转换将输入转换为正确的输出形状。
以下代码将输入 xml(假设它位于 caled input
的字符串变量中)转换为 MemoryStream。
通过 XSLT 将输入转换为流
// Create an XSLT Transformer
var xslt = new XslCompiledTransform();
xslt.Load("copydoc.xslt");
var settings = new XmlWriterSettings
{
Encoding = new UTF8Encoding(false) // NO BOM
};
// open all streams for reading and writing
using (var ms = new MemoryStream())
{
using (var xw = XmlWriter.Create(ms, settings))
{
// input is the string with the xml input
using (var sr = new StringReader(input))
using (var xr = XmlReader.Create(sr))
{
xslt.Transform(xr, xw);
// the memorystream now has the result
}
}
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
Copydoc.xslt
Xslt 文件相当简单,它使用两个模板和一个策略应用模板来获取<mgsn1:xmlDocument>
节点下的子节点:
<?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"
xmlns:mgns1="http://www.testing.com/"
exclude-result-prefixes="msxsl mgns1 "
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<!-- select the child node of xmlDocument-->
<xsl:apply-templates select="mgns1:PlaceXmlMessage/mgns1:xmlDocument/child::*" />
</xsl:template>
<!-- match each element -->
<xsl:template match="*">
<!-- make sure to get rid of the namespaces-->
<xsl:element name="{local-name(.)}">
<!-- be explicit about copying attributes -->
<xsl:apply-templates select="@*" />
<!-- copy childs-->
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- handle attributes -->
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
如果将文件 copydoc.xslt 添加到项目中,请不要忘记将 projectfile 属性Copy to output directory
设置为 copy always
否则将找不到 xslt 文件。
感谢您的帮助,我设法解决了这个问题
xmlDOM.LoadXml(p_strXmlDocument);
XmlElement root = xmlDOM.DocumentElement;
XmlNamespaceManager NameSpaceManager = new XmlNamespaceManager(new NameTable());
NameSpaceManager.AddNamespace("mgns1", "http://www.hidden.com/");
XmlNodeList nodeList = xmlDOM.SelectNodes("//mgns1:xmlDocument/*", NameSpaceManager);
string returnStr = "";
if (nodeList != null)
{
foreach (XmlNode node in nodeList)
{
returnStr += node.OuterXml;
}
}