Am trying to delete a list name containing the value "dfdfdfd" from an XPath
XmlNode names = LoadDocument(xml).DocumentElement.SelectSingleNode("//Class[#Name='" + getCurClass() + "']/Property[#Id='" + i + "']/Lists[contains(ListName,'ws_Users')]");
after I execute this statement:
names.RemoveChild(names.FirstChild);
but I nothing happens.
My XML :
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Class Name="ECMInstruction" Style="Top">
<Entity Id="1" Name="DocumentInformation" />
<Property Id="1">
</Property>
<Property Id="2">
<Lists>
<ListName>ws_Users</ListName>
<ListName>dfdfdfd</ListName>
</Lists>
</Property>
</Class>
</Root>
Thanks for the help
You need to save the modified XmlDocument object back to file :
XmlDocument doc = LoadDocument(xml);
XmlNode names = doc.DocumentElement.SelectSingleNode("//Class[#Name='" + getCurClass() + "']/Property[#Id='" + i + "']/Lists[contains(ListName,'ws_Users')]");
names.RemoveChild(names.FirstChild);
//save `doc` back to file :
doc.Save("path_to_the_xml_file.xml");
or this way :
XmlNode names = LoadDocument(xml).DocumentElement.SelectSingleNode("//Class[#Name='" + getCurClass() + "']/Property[#Id='" + i + "']/Lists[contains(ListName,'ws_Users')]");
names.RemoveChild(names.FirstChild);
//save owner `XmlDocument` back to file :
names.OwnerDocument.Save("path_to_the_xml_file.xml");
Related
I have an XML file that we are using systemlink for in AS400. I have the working XML file and if I just do a load document on the button click it writes to the database the hard coded values. However, I would like to patch values from textboxes in. Here is my XML:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE System-Link SYSTEM 'SystemLinkRequest.dtd'>
<System-Link>
<Login userId='' password='' maxIdle='900000'
properties='com.pjx.cas.domain.EnvironmentId=RN,
com.pjx.cas.domain.SystemName=,
com.pjx.cas.user.LanguageId=en'/>
<Request sessionHandle='*current' workHandle='*new'
broker='EJB' maxIdle='1000'>
<Create name='newObject_ITItemLocation_Default' domainClass='EXT0149' retainResult='false'>
<ApplyTemplate clientClass='EXT0149'>
<![CDATA[Asset]]>
</ApplyTemplate>
<DomainEntity>
<Property path='ponum'>
<Value><![CDATA[P21851]]></Value>
</Property>
<Property path='itmnbr'>
<Value><![CDATA[909520]]></Value>
</Property>
<Property path='itmcls'>
<Value><![CDATA[1]]></Value>
</Property>
<Property path='itmloc'>
<Value><![CDATA[1]]></Value>
</Property>
<Property path='srnum'>
<Value><![CDATA[]]></Value>
</Property>
</DomainEntity>
</Create>
And here is my C#:
enterXmlDocument document = new XmlDocument();
document.Load(Server.MapPath("~/addNew.xml"));
XmlElement po = document.GetElementById("ponum");
po.Value = poTextBox.Text;
document.Save(Server.MapPath("~/addNew.xml"));
Every time I try and run it I get an object not found so I'm guessing it can't find the ponum field. I'd like to patch the poTextBox.Text in where it is currently P21851. Any suggestions like I said if I just do the document.Load on button click it writes to the DB just fine, I just want to patch my values in.
Why dont you use serialization for converting the xml into an object so you can do what ever you want? Do you have the xsd?
Decided to take a different approach and just put it into a string and did an HttpWebRequest so that I could just patch in my values into my string. Thanks for the answers one day I'll mess with how to make that work in an XML document.
string asset = "<?xml version='1.0' encoding='UTF-8'?>" + "<!DOCTYPE System-Link SYSTEM 'SystemLinkRequest.dtd'>" + "<System-Link>" + "<Login userId='' password='' maxIdle='900000' properties='com.pjx.cas.domain.EnvironmentId=RN, com.pjx.cas.domain.SystemName=,com.pjx.cas.user.LanguageId=en'/>" + "<Request sessionHandle='*current' workHandle='*new' broker='EJB' maxIdle='1000'>" + "<Create name='newObject_ITItemLocation_Default' domainClass='EXT0149' retainResult='false'>" + "<ApplyTemplate clientClass='EXT0149'>" + "<![CDATA[Asset]]>" + "</ApplyTemplate>" + "<DomainEntity>" + "<Property path='ponum'><Value><![CDATA[" + poTextBox.Text + "]]></Value></Property>" + "<Property path='itmnbr'><Value><![CDATA[" + itemNoTextBox.Text + "]]></Value></Property>" + "<Property path='itmcls'><Value><![CDATA[" + classDropDown.SelectedValue +"]]></Value></Property>" + "<Property path='itmloc'><Value><![CDATA[" + locationDropDown.SelectedValue + "]]></Value></Property>" + "<Property path='srnum'><Value><![CDATA["+ serialTextBox.Text +"]]></Value></Property>" + "</DomainEntity>" + "</Create>" + "</Request>" + "</System-Link>";
String wRequestString = "SystemLinkRequest=" + HttpUtility.UrlEncode(asset);
I am getting the error : NullReferenceException was unhandled by user code , object reference not set to an instance of an object. While I want to change the element of an xml file. this is the code the error is generated on :
doc2.SelectSingleNode("/Document/CstmrCdtTrfInitn/GrpHdr/MsgId", nsmgr).InnerText = bank.Afkorting + "-0001";
This is the previous code :
XmlDocument doc2 = new XmlDocument();
doc2.Load(#"C:\Users\Kevin\Desktop\xsd\betalingen_sepa.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc2.NameTable);
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
DagboekFinancieel bank = os.FindObject<DagboekFinancieel>(CriteriaOperator.Parse("[Omschrijving] = ?", opdracht.Bank));
doc2.SelectSingleNode("/Document/CstmrCdtTrfInitn/GrpHdr/MsgId", nsmgr).InnerText = bank.Afkorting + "-0001";
string naamFile = bank.Afkorting + "-0001";
doc2.Save(#"C:\" + naamFile + ".xml");
This is the original XML file I got :
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
<CstmrCdtTrfInitn>
<GrpHdr>
<MsgId>#ref_xml#</MsgId>
<CreDtTm>#datum_tijd_xml#</CreDtTm>
<NbOfTxs>#aantal_transacties#</NbOfTxs>
<InitgPty>
<Nm>#afzender_naam#</Nm>
<Id>
<OrgId>
<Othr>
<Id>#afzender_btw_nr#</Id>
<Issr>KBO-BCE</Issr>
</Othr>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>#ref_payment_block#</PmtInfId>
<PmtMtd>TRF</PmtMtd>
<BtchBookg>true</BtchBookg>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
</PmtTpInf>
<ReqdExctnDt>#datum_uitvoering#</ReqdExctnDt>
<Dbtr>
<Nm>#afzender_naam#</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>#afzender_iban#</IBAN>
</Id>
</DbtrAcct>
<DbtrAgt>
<FinInstnId>
<BIC>#afzender_bic#</BIC>
</FinInstnId>
</DbtrAgt>
<ChrgBr>#kosten#</ChrgBr>
<CdtTrfTxInf>
<PmtId>
<EndToEndId>#ref_end_to_end#</EndToEndId>
</PmtId>
<Amt>
<InstdAmt Ccy="#munt#">#bedrag#</InstdAmt>
</Amt>
<CdtrAgt>
<FinInstnId>
<BIC>#leveran_bic#</BIC>
</FinInstnId>
</CdtrAgt>
<Cdtr>
<Nm>#leveran_naam#</Nm>
<PstlAdr>
<Ctry>#leveran_land#</Ctry>
<AdrLine>#leveran_straat#</AdrLine>
<AdrLine>#leveran_wpl#</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>#leveran_iban#</IBAN>
</Id>
</CdtrAcct>
<RmtInf>
<Ustrd>#leveran_ref#</Ustrd>
<Strd>
<CdtrRefInf>
<Tp>
<CdOrPrtry>
<Cd>#gestruct_mededeling_soort1#</Cd>
</CdOrPrtry>
<Issr>#gestruct_mededeling_soort2#</Issr>
</Tp>
<Ref>#gestruct_mededeling#</Ref>
</CdtrRefInf>
</Strd>
</RmtInf>
</CdtTrfTxInf>
</PmtInf>
</CstmrCdtTrfInitn>
</Document>
Your xml namespace is not correct. Use it like
nsmgr.AddNamespace("ns", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
doc2.SelectSingleNode("/ns:Document/ns:CstmrCdtTrfInitn/ns:GrpHdr/ns:MsgId", nsmgr).InnerText = "some text";
Am trying to add a new element called entity after the last entity but it keeps adding it inside the selected entity. To understand better this is my xml sample.
<Root>
<Class Name="ECMInstruction" Style="Top">
<Entity Id="1" Name="DocumentInformation" />
<Entity Id="2" Name="CustomerInformation" />
<Property Id="1" Name="DocumentTitle">
</Property>
<Property Id="2" Name="DateCreated">
<Lists>
<ListName>ws_Users</ListName>
<ListName>dfdfdfd</ListName>
</Lists>
</Property>
<Property Id="3" Name="Deadline">
</Property>
</Class>
</Root>
This is how it looks like after is inserted. I've tried using insertAfter but it gives me error.
<Entity Id="1" Name="DocumentInformation">
<Entity Id="2" Name="sds" />
</Entity>
The code:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("sample.xml");
XmlNodeList cnode = xmldoc.DocumentElement.SelectNodes("//Class[#Name='" + CurrentClass + "']/Entity");
foreach (XmlNode c in cnode)
{
int value = 0;
String entitycount = cnode.Count.ToString();
int.TryParse(entitycount, out value);
value = value + 1;
XmlElement root = xmldoc.CreateElement("Entity");
root.SetAttribute("Id", value.ToString());
root.SetAttribute("Name", EntityNametxt.Text);
c.AppendChild(root);
xmldoc.Save("sample.xml");
}
"I've tried using insertAfter but it gives me error. "
As per documentation, InsertAfter() should be called on parent node of referenced XmlNode (the 2nd argument of the method), otherwise ArgumentException will be thrown :
//instead of this : c.AppendChild(root);
//..you could do as follow :
c.ParentNode.InsertAfter(root, c);
I'm using XDocument to parse my XML File, but when I try to read the line number of a XNode or a XElement, it's always equal to zero.
I tried different ways to parse it:
foreach (XElement node in xDoc.Root.Descendants("nodeName"))
or
xDoc.XPathSelectElement("nodeName")
and each time ((IXmlLineInfo)node).LineNumber returns 0!
I'm using a XmlNamespaceManager.
Did I miss something?
Thanks in advance!
Edit :
Here is the concerned Xml as asked.
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance">
<CstmrDrctDbtInitn>
<GrpHdr>
<MsgId>XXXXXXXXX</MsgId>
<CreDtTm>2013-06-12T00:00:00</CreDtTm>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>136.82</CtrlSum>
<InitgPty>
<Nm>name</Nm>
<Id>
<OrgId>
<Othr>
<Id>XXXXXXXXX</Id>
</Othr>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<PmtInf>
<PmtInfId>275-20130612-FIRST</PmtInfId>
<PmtMtd>DD</PmtMtd>
<BtchBookg>true</BtchBookg>
<NbOfTxs>1</NbOfTxs>
<CtrlSum>136.82</CtrlSum>
<PmtTpInf>
<SvcLvl>
<Cd>SEPA</Cd>
</SvcLvl>
<LclInstrm>
<Cd>CORE</Cd>
</LclInstrm>
<SeqTp>RCUR</SeqTp>
</PmtTpInf>
<ReqdColltnDt>2013-06-05</ReqdColltnDt>
<Cdtr>
<Nm>name</Nm>
<PstlAdr>
<Ctry>BE</Ctry>
<AdrLine>XXXXXXXXX</AdrLine>
<AdrLine>XXXXXXXXX</AdrLine>
</PstlAdr>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>XXXXXXXXX</IBAN>
</Id>
</CdtrAcct>
<CdtrAgt>
<FinInstnId>
<BIC>XXXXXXXXX</BIC>
</FinInstnId>
</CdtrAgt>
<ChrgBr>SLEV</ChrgBr>
<CdtrSchmeId>
<Id>
<PrvtId>
<Othr>
<Id>XXXXXXXXX</Id>
<SchmeNm>
<Prtry>SEPA</Prtry>
</SchmeNm>
</Othr>
</PrvtId>
</Id>
</CdtrSchmeId>
<DrctDbtTxInf>
<PmtId>
<InstrId>XXXXXXXXX</InstrId>
<EndToEndId>XXXXXXXXX</EndToEndId>
</PmtId>
<InstdAmt Ccy="EUR">136.82</InstdAmt>
<DrctDbtTx>
<MndtRltdInf>
<MndtId>XXXXXXXXX</MndtId>
<DtOfSgntr>2009-10-31</DtOfSgntr>
<AmdmntInd>false</AmdmntInd>
<AmdmntInfDtls>
<AmdmntInd>yellowland</AmdmntInd>
<OrgnlMndtId>XXXXXXXXX</OrgnlMndtId>
<OrgnlCdtrSchmeId>
<Id>
<PrvtId>
<Othr>
<Id>XXXXXXXXX</Id>
<SchmeNm>
<Prtry>SEPA</Prtry>
</SchmeNm>
</Othr>
</PrvtId>
</Id>
</OrgnlCdtrSchmeId>
</AmdmntInfDtls>
</MndtRltdInf>
</DrctDbtTx>
<DbtrAgt>
<FinInstnId>
<BIC>XXXXXXXXX</BIC>
</FinInstnId>
</DbtrAgt>
<Dbtr>
<Nm>TEST</Nm>
<PstlAdr>
<Ctry>BE</Ctry>
<AdrLine>XXXXXXXXX</AdrLine>
<AdrLine>XXXXXXXXX</AdrLine>
</PstlAdr>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>XXXXXXXXX</IBAN>
</Id>
</DbtrAcct>
<RmtInf>
<Ustrd>test</Ustrd>
</RmtInf>
</DrctDbtTxInf>
</PmtInf>
</CstmrDrctDbtInitn>
</Document>
The LineInformations are not always loaded, when you load xml via XDocument.
You need to specify that you also want to load the LineInformation when you load the XML. That is done by using one of the Load methods that you can pass in a value of LoadOptions of the XDocument class.
var document = XDocument.Load(file, LoadOptions.SetLineInfo);
From here
XDocument xdoc = XDocument.Load(file);
IEnumerable<XElement> nodes = xdoc.Descendants("nodeName");
foreach (XElement node in nodes)
{
IXmlLineInfo info = node;
int lineNumber = info.LineNumber;
}
I know this is a very basic question but I'm new to XML and while it seems simple, I can't find a simple answer anywhere. I have an XML document that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<root version="1">
<targets>
<target type="email">
<property name="to">b1q23#email.com</property>
</target>
<target type="fob"/>
</targets>
<observation uniqueID="00A60D" deviceID="308610ea23">
<field name="field1">test1</field>
<field name="field2">test2</field>
</observation>
and I'm trying to either select a subset of that xml, or remove nodes, to get it pared down to:
<observation uniqueID="00A60D" deviceID="308610ea23">
<field name="attachments">
<string>1910.jpg</string>
</field>
<field name="field1">test1</field>
<field name="field2">test2</field>
</observation>
So that I can deserialize it into an object. Any help is greatly appreciated.
You can use XPath:
string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<root version=\"1\">" +
"<targets>" +
"<target type=\"email\">" +
"<property name=\"to\">b1q23#email.com</property>" +
"</target>" +
"<target type=\"fob\"/>" +
"</targets>" +
"<observation uniqueID=\"00A60D\" deviceID=\"308610ea23\">" +
"<field name=\"field1\">test1</field>" +
"<field name=\"field2\">test2</field>" +
"</observation>" +
"</root>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlElement root = doc.DocumentElement;
var observationNode = root.SelectSingleNode("/root/observation");
var observationXml = observationNode.OuterXml;
Here is a XML to LINQ Version:
dynamic root= XElement.Load(dataStream).Descendants("root")
.Select(element => element.Value).ToArray();
This will give all the root element from the document.And you can access root
XElement root = XElement.Parse("<root version ..." // etc. to parse a string.
// Use XElement.Load to load a file.
var observations = root.Elements("observation");
It assumes one root (by definition) and possibly multiple observation elements.