如何分别输出子元素,而不是一个以空格分隔的字符串?

时间:2016-10-20 09:53:11

标签: xml powershell

我目前在XML中选择某些属性的代码似乎不起作用:

<script> 
   $(function(){
      $('.insert_external').load("external.html",function(){
           setText();
   }); 
   });
</script>

<script> 
    $(function(){
        function setText(){
           length = document.getElementsByClassName("ToChange").length;
           for (i = 0; i < length; i++) {
               document.getElementsByClassName("ToChange")[i].innerHTML = "New Text";
           }
        }
    });
</script>

输出:

1:Aminoacids_Routine_2016_05_30_002:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23:Leu Iso Thre Val Lys Met Phen Try His Gly Ala Ser Arg Cys Tyr Pro Glu Glut Asp Aspa Tau Orn Cit:0.0000000000     0.0000000000   0.0000000000  0.0000000000 0.0000000000  0.0000000000  0.0000000000
2:Aminoacids_Routine_2016_05_30_003:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23:Leu Iso Thre Val Lys Met Phen Try His Gly Ala Ser Arg Cys Tyr Pro Glu Glut Asp Aspa Tau Orn Cit:0.0000000000 0.2336617286 0.2147717292 0.2252815136  0.2299108827 0.2395318825  0.0000000000    0.0000000000 0.0000000000  0.2074479299     0.0000000000  0.0000000000

但我希望输出看起来像这样:

1;Aminoacids_Routine_2016_05_30_002;1;Leu;0.0000000000
2;Aminoacids_Routine_2016_05_30_002;2;Iso;0.0000000000
...
1;Aminoacids_Routine_2016_05_30_003;1;Leu;0.0000000000
2;Aminoacids_Routine_2016_05_30_003;2;Iso;0.2336617286
...

XML文件:

class TodosPage extends Component {

constructor(props) {
    super(props);
    this.state = {
        listSelected: "",
    };
}

selectList(listId) {
    this.setState({ listSelected: listId });
}

renderLists() {
    return this.props.lists.map((list) => (
        <List 
            selectedItemId={this.state.listSelected}
            selectList={() => this.selectList(list._id)}
            key={list._id}
            list={list}
            countPendingTasks={this.countPendingTasks(list._id)}
        />
    ));
}

render() {
    return (
        <div className="container">
                <ListForm />
                <ListGroup>
                    {this.renderLists()}
                </ListGroup>

2 个答案:

答案 0 :(得分:2)

@wOxxOm一样,我将SelectNodes()XPath expression一起使用,但我会将输出处理为calculated properties而不是:

$xml.SelectNodes('//COMPOUND') |
  Select-Object @{n='SampleID';e={[int]$_.ParentNode.id}},
                @{n='SampleName';e={$_.ParentNode.name}},
                @{n='CompoundID';e={[int]$_.id}},
                @{n='CompoundName';e={$_.name}},
                @{n='analconc';e={[double]$_.PEAK.analconc}}

这将使您使用对象而不是字符串。如果您需要将数据写入文件,可以通过Export-Csv导出:

... | Export-Csv 'C:\path\to\quandata.csv' -NoType -Delimiter ';'

答案 1 :(得分:1)

您未使用XPath selectors,而是使用本机PowerShell对象属性访问。

PowerShell 3.0和更新版本在整个数组上使用时会自动生成指定属性值的数组。

对于XML,每个重复的元素如COMPOUND在按名称访问时返回一个数组(没有索引),因此上述行为适用于$_.COMPOUND.id:这是一个数组!并且通过将元素与代码中的空格连接,它会自动类型强制转换为字符串。

解决方案1:手动枚举子元素:

$delim = ':'
foreach ($sample in $xml.QUANDATASET.GROUPDATA.GROUP.SAMPLELISTDATA.SAMPLE) {
    foreach ($compound in $sample.COMPOUND) {
        $sample.id, $sample.name,
        $compound.id, $compound.name, [double]$compound.PEAK.analconc -join $delim
    }
}

解决方案2:实际上使用XPath选择所有子元素并访问SAMPLE parentNode

$delim = ':'
foreach ($compound in $xml.SelectNodes('//COMPOUND')) {
    $sample = $compound.ParentNode
    $sample.id, $sample.name,
    $compound.id, $compound.name, [double]$compound.PEAK.analconc -join $delim
}

而不是管道传输我使用foreach语句来获得一个名称很好的迭代器变量。