I'm trying to drill down through a shapetree in a PowerPoint slide to get a shape's placeholder values. The shape on the shapetree looks like this:
<p:sp>
<p:nvSpPr>
<p:cNvPr id="10" name="Text Placeholder 2"/>
<p:cNvSpPr>
<a:spLocks noGrp="1"/>
</p:cNvSpPr>
<p:nvPr>
<p:ph type="body" sz="quarter" idx="13" hasCustomPrompt="1"/>
</p:nvPr>
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="457200" y="3276601"/>
<a:ext cx="8229600" cy="838199"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</p:spPr>
<p:txBody>
<a:bodyPr lIns="91421" tIns="45710" rIns="91421" bIns="45710"/>
<a:lstStyle>
<a:lvl1pPr marL="0" indent="0" algn="ctr">
<a:buFontTx/>
<a:buNone/>
<a:defRPr sz="2400" b="1" baseline="0">
<a:solidFill>
<a:schemeClr val="tx1"/>
</a:solidFill>
<a:latin typeface="+mj-lt"/>
<a:cs typeface="Arial" pitchFamily="34" charset="0"/>
</a:defRPr>
</a:lvl1pPr>
</a:lstStyle>
<a:p>
<a:pPr lvl="0"/>
<a:r>
<a:rPr lang="en-US" dirty="0" smtClean="0"/>
<a:t>Click to enter course title</a:t>
</a:r>
</a:p>
</p:txBody>
</p:sp>
The part I'm interested in getting looks like this:
<p:nvPr>
<p:ph type="body" sz="quarter" idx="13" hasCustomPrompt="1"/>
</p:nvPr>
I'm trying to get the idx value (13, in this case).
The statement I'm using looks like this, so far (I'm saying "so far" because I don't know how to finish the statement):
var index = shape.NonVisualShapeProperties.NonVisualShapeDrawingProperties. <-???
At this point in the code, I have the shape I want, I just can't figure out how to get the placeholder values using Open Office SDK. I guess I could just treat it as plain old XML and get it by element name, but I figured the OOXML SDK would have some method built-in for this.
Finally figured out how to do this:
index = int.Parse(shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape.Index);
I was using NonVisualShapeDrawingProperties when I should have been using ApplicationNonVisualDrawingProperties.
Related
I have an example of my XML below (which i'm converting from SGML to XML prior to the check but that's besides the point). The XML IS valid at the point of checking.
I need check the XDocument and find out if any of the <version> elements contained within the <status> section at the top of the file contain the attriubute "RNWB". I need to be explicit about the fact that i'm only interested in checking <version> elements that are children of <status> elements because there might be other <version> elements within the document which i don't care about.
<dmodule>
<idstatus>
<dmaddres>
<dmc>Blah</dmc>
<dmtitle><techname>System</techname><infoname>Introduction</infoname></dmtitle>
<issno issno="006" type="revised"/>
<issdate year="2016" month="11" day="30"/>
</dmaddres>
<status>
<security class="2"/>
<rpc></rpc>
<orig></orig>
<applic>
<model model="2093">
<version version="BASE"></version>
<version version="RNWB"></version></model>
</applic>
<techstd>
<autandtp>
<authblk></authblk>
<tpbase></tpbase>
</autandtp>
<authex></authex>
<notes></notes>
</techstd>
<qa>
<firstver type="tabtop"/></qa>
<remarks></remarks>
</status>
</idstatus>
<content>
<refs><norefs></refs>
<descript>
<para0><title>Introduction</title>
<para>The system many new features included which are safe and accurate blah blah blah.</para>
</descript>
</content>
</dmodule>
I've tried all sorts but can't seem to get a result. Here's one example of what i've tried:
var result = (from ele in doc.Descendants("applic").Descendants("version").Attributes("RNWB")
select ele).ToList();
foreach (var v in result)
{
File.Move(file, Path.Combine(outputFolder, fileName)); // move the file to the new folder
}
If you have to be explicit that the version element is within a status element, then you need to be explicit about that in your query too. Your example doesn't include version anywhere.
You then need to find a version attribute with the value RNWB. You're currently looking for an RNWB attribute, which doesn't exist.
var hasFlag = doc
.Descendants("status")
.Descendants("version")
.Attributes("version")
.Any(x => x.Value == "RNWB");
See this fiddle for a demo.
Something like this should work:
// Load document
XDocument _doc = XDocument.Load("C://t//My File2.txt");
Select path to model
Select the elements version
Where the attribute == RNWB
Put them in a list for the result
// if you need to get the version element where the atrribute == something
List<XElement> model = _doc
.XPathSelectElement("dmodule/idstatus/status/applic/model")
.Elements("version")
.Where(x => x.Attribute("version").Value == "RNWB")
.ToList();
// if you only need to check if the attribute exists
bool contains = _doc
.XPathSelectElement("dmodule/idstatus/status/applic/model")
.Elements("version")
.Any(x => x.Attribute("version").Value == "RNWB");
The XML is not in valid format: I made some adjustment and got it working
<dmodule>
<idstatus>
<dmaddres>
<dmc>Blah</dmc>
<dmtitle><techname>System</techname><infoname>Introduction</infoname></dmtitle>
<issno issno="006" type="revised"/>
<issdate year="2016" month="11" day="30"/>
</dmaddres>
<status>
<security class="2"/>
<rpc></rpc>
<orig></orig>
<applic>
<model model="2093">
<version version="BASE"></version>
<version version="RNWB"></version>
</model>
</applic>
<techstd>
<autandtp>
<authblk></authblk>
<tpbase></tpbase>
</autandtp>
<authex></authex>
<notes></notes>
</techstd>
<qa>
<firstver type="tabtop"/></qa>
<remarks></remarks>
</status>
</idstatus>
<content>
<refs>
<norefs>
</norefs>
</refs>
<descript>
<para0>
<title>Introduction</title>
<para>The system many new features included which are safe and accurate blah blah blah.</para>
</para0>
</descript>
</content>
</dmodule>
I have a docx file and want to generate a list of picture filenames/unique ids combinations.
Here is the relevant piece of the docx file:
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="2C4CE07B" wp14:editId="12367BBF">
...
...
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="2" name="ProfileGraph.png" />
<pic:cNvPicPr />
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId9">
<a:extLst>
so I need rId9 and ProfileGraph.png in one directory entry.
I can find the rId9:
var blipElements = from drawing in drawingElements
where drawing.Descendants<A.Blip>().Count() > 0
select drawing.Descendants<A.Blip>().First();
But I don't know how to get the cNvPr-elements belonging to each of the Blips in blipElements.
I was thinking in the line of
var names = from blip in blipElements
where blip.Ancestors<Picture>().First<Picture>().Descendants<....>()
Any help would be appreciated.
How about something like
var body = doc.MainDocumentPart.Document.Body;
var pics = body.Descendants<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
var result = pics.Select(p => new
{
Id = p.BlipFill.Blip.Embed.Value,
Name = p.NonVisualPictureProperties.NonVisualDrawingProperties.Name.Value
});
Where doc is assumed to be an already opened WordProcessingDocument object.
The result variable will be an IEnumerable of an anonymous type containg Id and Name properties.
I'm not particularly knowledgable on the word processing OpenXML stuff but, in theory, the Embed and Name properties could be null so I suppose you might have to test for null before accessing the '.Value' property.
I've already parsed a horrible document into a list, but I'm having issues formatting it with Linq and cant seem to get it quite right.
My code looks like this:
var xEle = new XElement("WorkOrder",
from item in items
select new XElement(item.SECTION,
new XElement(item.DATANAME, item.DATAVALUE)));
Which produces something like this:
<WorkOrder>
<JOBDETAILS>
<JOBNUMBER>12345</JOBNUMBER>
</JOBDETAILS>
<JOBDETAILS>
<ACTIVITYNO>/01</ACTIVITYNO>
</JOBDETAILS>
<JOBDETAILS>
<JOBCCD>15/06/2015
</JOBCCD>
</JOBDETAILS>
<JOBDETAILS>
<REQUIRED>15/06/2016
</REQUIRED>
</JOBDETAILS>
<COMPANYDETAILS>
<COMPANY>Adventure Works
</COMPANY>
</COMPANYDETAILS>
<COMPANYDETAILS>
<STREET>LTD
</STREET>
</COMPANYDETAILS>
<COMPANYDETAILS>
<LOCALITY>123 Street
</LOCALITY>
</COMPANYDETAILS>
<COMPANYDETAILS>
<TOWN>Local Town
</TOWN>
</COMPANYDETAILS>
<COMPANYDETAILS>
<COUNTY>County Name
</COUNTY>
</COMPANYDETAILS>
<COMPANYDETAILS>
<POSTCODE>ABC 1234
</POSTCODE>
<COMMENTS>
<COMMENT>this is a comment</COMMENT>
</COMMENTS>
</WorkOrder>
I'm trying to get it to be grouped by my item.SECTION (in the example output this would be JOBDETAILS & COMPANYDETAILS) which I want to produce something like this:
<WorkOrder>
<JOBDETAILS>
<JOBNUMBER>12345</JOBNUNMBER>
<ACTIVITYNO>/01</ACTIVITYNO>
<JOBCCD>15/06/2015</JOBCCD>
<REQUIRED>15/06/2016</REQUIRED>
</JOBDETAILS>
<COMPANYDETAILS>
<COMPANY>Adventure Works</COMPANY>
<STREET>LTD</STREET>
<LOCALITY>123</LOCALITY>
</COMPANYDETAILS>
<COMMENTS>
<COMMENT>THIS IS A COMMENT</COMMENT>
</COMMENTS>
</WorkOrder>
My list is dynamic and does not contain a specific set of fields each time, hence why I have not hard coded the output.
I dont think I'm a million miles away, and would appreciate a kick in the right direction.
You need to add a groupby to group the results by the section.
var xEle =
new XElement("WorkOrder",
from item in items
group item by item.SECTION into g
select new XElement(g.Key,
g.Select(i => new XElement(i.DATANAME, i.DATAVALUE))));
Note that you also need two selects, one to build up the list of elements and another to wrap them together. (Note that I used function syntax by you could also say a variant of from i in g select)
I'm trying to read in some XML data but I'm getting an error I've never spotted before. Can anyone shed some light on this?
The error:
Screen name: System.Xml.Linq.Extensions+c__Iterator5
UnityEngine.Debug:Log(Object)
HV_ReadSettingsFile:Update() (at Assets/_scripts/HV_ReadSettingsFile.cs:64)
Here is my code reading in the XML and is ultimately generating the error:
var xdoc = XDocument.Load(#"C:\\Test.xml");
var screen = xdoc.Descendants("Screen");
foreach (var Screen in screen)
{
HV_Screen _screen = new HV_Screen();
_screen.Name = Convert.ToString(Screen.Descendants("Name").Attributes("Name"));
Debug.Log("Screen name: " + _screen.Name);
}
And my XML sheet:
<Settings>
<Display_Settings>
<Screen>
<Name Name="Screen" />
<ScreenTag Tag="Screen Tag" />
<LocalPosition X="12" Y="81" Z="28" />
<Width Width="54" />
<Height Height="912" />
</Screen>
<Screen>
<Name Name="Screen" />
<ScreenTag Tag="Screen Tag" />
<LocalPosition X="32" Y="21" Z="28" />
<Width Width="54" />
<Height Height="912" />
</Screen>
</Display_Settings>
</Settings>
That's not an error. That's logging exactly what you've asked for. You've asked for all the Name attributes in all the Name elements... but then you're trying to log that sequence as a single value.
I think you want:
var screens = xdoc.Descendants("Screen");
foreach (var screen in screens)
{
HV_Screen _screen = new HV_Screen();
_screen.Name = (string) screen.Element("Name").Attribute("Name");
Debug.Log("Screen name: " + _screen.Name);
}
This is now looking for one element and one attribute per Screen element. Note that I've changed the variable names to follow normal .NET conventions, other than _screen as I don't know what HV_Screen is meant to be.
It's not really clear why you've got separate elements for Width, Height and Name, each with an attribute matching the element name - and ScreenTag nearly doing so. If the XML is under your control, you might consider either:
<Screen Name="Screen" Width="54" Height="912" Tag="Screen Tag">
<LocalPosition X="12" Y="81" Z="28" />
</Screen>
or perhaps:
<Screen>
<Name>Screen</Name>
<ScreenTag>Screen Tag</ScreenTag>
<LocalPosition X="12" Y="81" Z="28" />
<Width>54</Width>
<Height>912</Height>
</Screen>
Also, if you're trying to build a collection of HV_Screen items, you probably want to use a query rather than a foreach loop - but it's not clear what you're actually trying to do beyond logging debug information at the moment.
You can try to do:
var xdoc = XDocument.Load(#"C:\\test.xml");
List<string> lstScreen = xdoc.Descendants("Screen").Select(x => x.Element("Name").Attribute("Name").Value).ToList();
foreach (string name in lstScreen)
{
...
I hope help you!!
I'm trying to find the inner text value of an element using LINQ-to-XML (an XElement object). I make my service call and get an XML response back that I've successfully loaded into an XElement object. I want to extract the inner text of one of the elements - however, every time I try to do this, I get a null result.
I feel like I'm missing something super-simple, but I'm fairly new to LINQ-to-XML. Any help is appreciated.
I'm trying to get the inner text value of the StatusInfo/Status element. Here's my XML document that's returned:
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
<title type="text">My Response</title>
<id>tag:foo.com,2012:/bar/06468dfc-32f7-4650-b765-608f2b852f22</id>
<author>
<name>My Web Services</name>
</author>
<link rel="self" type="application/atom+xml" href="http://myServer/service.svc/myPath" />
<generator uri="http://myServer" version="1">My Web Services</generator>
<entry>
<id>tag:foo.com,2012:/my-web-services</id>
<title type="text" />
<updated>2012-06-27T14:22:42Z</updated>
<category term="tag:foo.com,2008/my/schemas#system" scheme="tag:foo.com,2008/my/schemas#type" />
<content type="application/vnd.my.webservices+xml">
<StatusInfo xmlns="tag:foo.com,2008:/my/data">
<Status>Available</Status> <!-- I want the inner text -->
</StatusInfo>
</content>
</entry>
</feed>
Here's a snippet of code that I'm using to extract the value (which doesn't work):
XElement root = XElement.Load(responseReader);
XNamespace tag = "tag:foo.com,2008:/my/data";
var status = (from s in root.Elements(tag + "Status")
select s).FirstOrDefault();
My status variable is always null. I've tried several variations on this, but to no avail. The part that's confusing me is the namespace -- tag and 2008 are defined. I don't know if I'm handling this correctly or if there's a better way to deal with this.
Also, I don't have control over the XML schema or the structure of the XML. The service I'm using is out of my control.
Thanks for any help!
Try Descendants() instead of Elements():
XElement x = XElement.Load(responseReader);
XNamespace ns = "tag:foo.com,2008:/my/data";
var status = x.Descendants(ns + "Status").FirstOrDefault().Value;
There are 2 Namespaces in the feed:
the Atom namespace
the tag namespace
The outer xml needs to use the Atom namespace, while a portion of the inner xml needs to use the tag namespace. i.e.,
var doc = XDocument.Load(responseReader);
XNamespace nsAtom = "http://www.w3.org/2005/Atom";
XNamespace nsTag = "tag:foo.com,2008:/my/data";
// get all entry nodes / use the atom namespace
var entry = doc.Root.Elements(nsAtom + "entry");
// get all StatusInfo elements / use the atom namespace
var statusInfo = entry.Descendants(nsTag + "StatusInfo");
// get all Status / use the tag namespace
var status = statusInfo.Elements(nsTag + "Status");
// get value of all Status
var values = status.Select(x => x.Value.ToString()).ToList();