Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更新xml值的脚本_Xml_Linux_Xslt_Awk_Gawk_Perl - Fatal编程技术网

更新xml值的脚本

更新xml值的脚本,xml,linux,xslt,awk,gawk,perl,Xml,Linux,Xslt,Awk,Gawk,Perl,我正在尝试使用AWK脚本根据条件对xml文件进行更新。有人能帮我吗 students.xml <students> <student> <stuId>1</stuId> <name>A</name> <mark>75</mark> <result></result> </student>


我正在尝试使用AWK脚本根据条件对xml文件进行更新。有人能帮我吗

students.xml

<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result></result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result></result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result></result>
    </student>
</students>

1.
A.
75
2.
B
35
1.
C
94
到目前为止我尝试过的代码

我能够使用下面的代码提取标记值

BEGIN { RS="<[^>]+>" } 
{ print  RT, $0 }
开始{RS=“]+>”}
{打印RT,$0}
这将按预期打印所有标记和值

我想将
标记更新为通过如果标记>40否则失败

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="student[mark >= 40]/result">
    <xsl:copy>pass</xsl:copy>
  </xsl:template>

  <xsl:template match="student[40 > mark]/result">
    <xsl:copy>fail</xsl:copy>
  </xsl:template>

</xsl:stylesheet>
输出

<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result>pass</result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result>fail</result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result>pass</result>
    </student>
</students>

1.
A.
75
通过
2.
B
35
失败
1.
C
94
通过

有人能在这方面帮助我吗?

不要试图用解析XML,而是使用真正的解析器:

XML文件是动态编辑的

与:

修改文件:

1.
A.
75
通过
2.
B
35
失败
1.
C
94
通过

我还建议避免使用
XML解析器/处理器
方法: 如果您不喜欢
perl
,可以通过使用
XSLT
使用完整的XML技术方法:

输入:

$ more students.xml
::::::::::::::
students.xml
::::::::::::::
<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result></result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result></result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result></result>
    </student>
</students>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform (copy everything) -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- when you reach result take action-->
<xsl:template match="result">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
                        <!-- fetch the value of mark of the parent node -->
                        <xsl:variable name="mark" select="../mark" />
                        <xsl:choose>
                        <!-- if over 40 -->
                         <xsl:when test="$mark > 40">
                           <xsl:text>pass</xsl:text>
                         </xsl:when>
                         <!-- else -->
                         <xsl:otherwise>
                           <xsl:text>fail</xsl:text>
                         </xsl:otherwise>
                   </xsl:choose>
    </xsl:copy>   
</xsl:template>

</xsl:stylesheet>
$ xsltproc --output students_grade.xml students.xsl  students.xml 
more students_grade.xml 
<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student>
    <stuId>1</stuId>
    <name>A</name>
    <mark>75</mark>
    <result>pass</result>
  </student>
  <student>
    <stuId>2</stuId>
    <name>B</name>
    <mark>35</mark>
    <result>fail</result>
  </student>
  <student>
    <stuId>1</stuId>
    <name>C</name>
    <mark>94</mark>
    <result>pass</result>
  </student>
</students>
输出:

$ more students.xml
::::::::::::::
students.xml
::::::::::::::
<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result></result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result></result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result></result>
    </student>
</students>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform (copy everything) -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- when you reach result take action-->
<xsl:template match="result">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
                        <!-- fetch the value of mark of the parent node -->
                        <xsl:variable name="mark" select="../mark" />
                        <xsl:choose>
                        <!-- if over 40 -->
                         <xsl:when test="$mark > 40">
                           <xsl:text>pass</xsl:text>
                         </xsl:when>
                         <!-- else -->
                         <xsl:otherwise>
                           <xsl:text>fail</xsl:text>
                         </xsl:otherwise>
                   </xsl:choose>
    </xsl:copy>   
</xsl:template>

</xsl:stylesheet>
$ xsltproc --output students_grade.xml students.xsl  students.xml 
more students_grade.xml 
<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student>
    <stuId>1</stuId>
    <name>A</name>
    <mark>75</mark>
    <result>pass</result>
  </student>
  <student>
    <stuId>2</stuId>
    <name>B</name>
    <mark>35</mark>
    <result>fail</result>
  </student>
  <student>
    <stuId>1</stuId>
    <name>C</name>
    <mark>94</mark>
    <result>pass</result>
  </student>
</students>
更多学生\u grade.xml
1.
A.
75
通过
2.
B
35
失败
1.
C
94
通过

另一个选项是使用

注意:命令行中的
-L
将在位编辑文件。如果这不是您想要的行为,请确保将其删除

您还可以将XSLT1.0与XMLSTARTET(the)一起使用

update.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="student[mark >= 40]/result">
    <xsl:copy>pass</xsl:copy>
  </xsl:template>

  <xsl:template match="student[40 > mark]/result">
    <xsl:copy>fail</xsl:copy>
  </xsl:template>

</xsl:stylesheet>

很好的perl解析解决方案+1!这一次,我也认为这是一个最好的解析器解决方案,我提出了一个XSLT解决方案!Bonne nuit au fait;-)给新来者的建议:如果一个答案解决了你的问题,请点击大复选标记接受它(✓) 在它旁边,也可以选择向上投票(向上投票要求至少15个信誉点)。如果您发现其他答案有帮助,请向上投票。接受和向上投票有助于未来的读者。请参阅[相关帮助中心文章][1][1]:stackoverflow.com/help/someone-answerry,感谢您的延迟回复。是的,确实如此。我正在将此示例方法用于实际实现,希望它在那里有效。如果我在那里遇到任何问题,我会让您知道。再次感谢大家