我有以下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>
答案 0 :(得分:2)
试试这个
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);
}
}
}
答案 1 :(得分:1)
您可以使用XSLT转换将输入转换为正确的输出形状。
以下代码将输入xml(假设它位于字符串变量caled input
中)转换为MemoryStream。
// 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()));
}
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文件。
答案 2 :(得分:0)
感谢您的帮助,我设法用
解决了这个问题 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;
}
}