I want to loop an XML tree and test two conditions and found some issues.
我想循环XML树并测试两个条件并发现一些问题。
- I can't compare a XElement like an Integer. I've read some other posts (besides this examples) and so far I couldn't figure it out. :S
我无法像整数那样比较XElement。我已经阅读了其他一些帖子(除了这个例子),到目前为止我无法弄明白。 :S
- In the foreach loop I'm only able to change the first matching element and I would like to do it for all matching XElements. I have tried Any() and All() but wasn't successful.
在foreach循环中,我只能更改第一个匹配元素,我想为所有匹配的XElements做。我尝试了Any()和All(),但没有成功。
My XML files: (for protein)
我的XML文件:(对于蛋白质)
<?xml version="1.0" encoding="utf-8"?>
<ProteinStructure>
<SecondaryStructure>
<StName>HELX_P1</StName>
<StType>alphaHelix</StType>
<AmAcidStart>1</AmAcidStart>
<AmAcidEnd>2</AmAcidEnd>
</SecondaryStructure>
<SecondaryStructure>
<StName>HELX_P2</StName>
<StType>alphaHelix</StType>
<AmAcidStart>43</AmAcidStart>
<AmAcidEnd>53</AmAcidEnd>
</SecondaryStructure>
My XML files: (for atom)
我的XML文件:(对于atom)
<?xml version="1.0" encoding="utf-8"?>
<Molecule>
<Atom>
<AtNum>1</AtNum>
<AmAcSeq>2</AmAcSeq>
<AtType>N</AtType>
<StType>turn</StType>
</Atom>
<Atom>
<AtNum>2</AtNum>
<AmAcSeq>2</AmAcSeq>
<AtType>CA</AtType>
<StType>turn</StType>
</Atom>
<Atom>
<AtNum>2</AtNum>
<AmAcSeq>2</AmAcSeq>
<AtType>C</AtType>
<StType>turn</StType>
</Atom>
<Atom>
<AtNum>1</AtNum>
<AmAcSeq>3</AmAcSeq>
<AtType>N</AtType>
<StType>turn</StType>
</Atom>
My code so far:
我的代码到目前为止:
XDocument atom = XDocument.Load (@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\__3Q26.xml");
XDocument protein = XDocument.Load (@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\_3Q26.xml");
//Change secondary structure tag type "turn" to helixAlpha or betaSheet
foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
{
atom.Element ("Molecule")
.Elements ("Atom")
.Where (x => (int?)x.Element("AmAcSeq") >= (int?)amAc.Element("AmAcidStart") && x => (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
.Select (x => x.Element("StType")).FirstOrDefault().SetValue(amAc.Element("StType"));
// Console.WriteLine (amAc.Element("AmAcidStart").Value);
// .Where (x => Convert.ToInt16(x.Element("AmAcSeq").Value) <= Convert.ToInt16(amAc.Element("AmAcidStart").Value) && x => Convert.ToInt16(x.Element ("AmAcSeq").Value) >= Convert.ToInt16(amAc.Element("AmAcidStart")))
// .Where (x => (int?)x.Element("AmAcSeq") >= (int?)amAc.Element("AmAcidStart") && x => (int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart"))
}
atom.Save(@"C:\Users\RuiGarcia\Documents\MIB\INESC\C#Tutorial\ProjectC#\Molecule_00\PDBLibary_00\Data\__3Q26.xml");
P.S. - How can I format correctly the code without separating it in the code sample?
附: - 如何在不将代码示例中的代码分开的情况下正确格式化代码?
Thanks in advance.
提前致谢。
2 个解决方案
#1
0
You need a second foreach
to iterate through the results. I lifted some values and included an example below of doing that.
您需要第二个foreach来遍历结果。我提出了一些价值观,并在下面举了一个例子。
XDocument atom = XDocument.Load (@"...\__3Q26.xml");
XDocument protein = XDocument.Load (@"...\_3Q26.xml");
//Change secondary structure tag type "turn" to helixAlpha or betaSheet
foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
{
int? start = (int?)amAc.Element("AmAcidStart");
int? end = (int?)amAc.Element("AmAcidEnd");
string stType = (string)amAc.Element("StType");
IEnumerable<XElement> atoms = atom.Element("Molecule").Elements("Atom");
// Here we are iterating again in each matching result
foreach (XElement atomElement in atoms.Where(elem => (int?)elem.Element("AmAcSeq") >= start && (int?)elem.Element("AmAcSeq") <= end))
{
atomElement.SetValue(stType);
}
}
#2
0
I see a couple problems here:
我在这看到几个问题:
- You need to use nested
foreach
loops rather than aFirstOrDefault()
. - Your condition
(int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart")
doesn't even compile, and should almost certainly be something like(int?)x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
您需要使用嵌套的foreach循环而不是FirstOrDefault()。
你的条件(int?)ToInt16.x.Element(“AmAcSeq”)<=(int?)amAc.Element(“AmAcidStart”)甚至不编译,几乎可以肯定是(int?)x.Element (“AmAcSeq”)<=(int?)amAc.Element(“AmAcidEnd”))
Thus:
foreach (XElement secondaryStructure in protein.Descendants ("SecondaryStructure"))
{
foreach (var atomStType in atom.Element ("Molecule")
.Elements ("Atom")
.Where(a => (int?)a.Element("AmAcSeq") >= (int?)secondaryStructure.Element("AmAcidStart") && (int?)a.Element("AmAcSeq") <= (int?)secondaryStructure.Element("AmAcidEnd"))
.Select (a => a.Element("StType")))
{
atomStType.SetValue((string)secondaryStructure.Element("StType"));
}
}
#1
0
You need a second foreach
to iterate through the results. I lifted some values and included an example below of doing that.
您需要第二个foreach来遍历结果。我提出了一些价值观,并在下面举了一个例子。
XDocument atom = XDocument.Load (@"...\__3Q26.xml");
XDocument protein = XDocument.Load (@"...\_3Q26.xml");
//Change secondary structure tag type "turn" to helixAlpha or betaSheet
foreach (XElement amAc in protein.Descendants ("SecondaryStructure"))
{
int? start = (int?)amAc.Element("AmAcidStart");
int? end = (int?)amAc.Element("AmAcidEnd");
string stType = (string)amAc.Element("StType");
IEnumerable<XElement> atoms = atom.Element("Molecule").Elements("Atom");
// Here we are iterating again in each matching result
foreach (XElement atomElement in atoms.Where(elem => (int?)elem.Element("AmAcSeq") >= start && (int?)elem.Element("AmAcSeq") <= end))
{
atomElement.SetValue(stType);
}
}
#2
0
I see a couple problems here:
我在这看到几个问题:
- You need to use nested
foreach
loops rather than aFirstOrDefault()
. - Your condition
(int?)ToInt16.x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidStart")
doesn't even compile, and should almost certainly be something like(int?)x.Element ("AmAcSeq") <= (int?)amAc.Element("AmAcidEnd"))
您需要使用嵌套的foreach循环而不是FirstOrDefault()。
你的条件(int?)ToInt16.x.Element(“AmAcSeq”)<=(int?)amAc.Element(“AmAcidStart”)甚至不编译,几乎可以肯定是(int?)x.Element (“AmAcSeq”)<=(int?)amAc.Element(“AmAcidEnd”))
Thus:
foreach (XElement secondaryStructure in protein.Descendants ("SecondaryStructure"))
{
foreach (var atomStType in atom.Element ("Molecule")
.Elements ("Atom")
.Where(a => (int?)a.Element("AmAcSeq") >= (int?)secondaryStructure.Element("AmAcidStart") && (int?)a.Element("AmAcSeq") <= (int?)secondaryStructure.Element("AmAcidEnd"))
.Select (a => a.Element("StType")))
{
atomStType.SetValue((string)secondaryStructure.Element("StType"));
}
}